Find all ranges of consecutive numbers from Array | Set -2 (using Exponential BackOff)
Last Updated :
31 Jan, 2023
Given a sorted array arr[] consisting of N integers without any duplicates, the task is to find the ranges of consecutive numbers from that array.
Examples:
Input: arr[] = {1, 2, 3, 6, 7}
Output: 1->3, 6->7
Explanation: There are two ranges of consecutive number from that array.
Range 1 = 1 -> 3
Range 2 = 6 -> 7
Input: arr[] = {-1, 0, 1, 2, 5, 6, 8}
Output: -1->2, 5->6, 8
Explanation: There are three ranges of consecutive number from that array.
Range 1 = -1 -> 2
Range 2 = 5 -> 6
Range 3 = 8
Approach 1: The approach using traversal of array has been discussed in Set 1 of this article. The idea is to traverse the array from the initial position and for every element in the array, check the difference between the current element and the previous element.
Time Complexity: O(N), where N is the length of the array.
Approach 2: Exponential Back-off
Exponential backoff is an algorithm that uses any sort of feedback/event to multiplicatively decrease the current rate of some process. This is used to achieve an acceptable/optimum rate. These algorithms find usage in a wide range of systems and processes, with radio networks and computer networks being particularly notable.
Instead of using linear incremental approach we will use exponential backoff as following:
- Fix your rate as exponential increment(i = i*2) instead of linear increment (i ++)
- At the exit condition (nums[i] - nums[0] != i), do the linear incremental in last half of the interval. i.e. ( i/2 -> i) instead of doing it for 0 to i.
This will help you achieve the optimal solution very fast as compared to linear incremental solution, because the nature of solution is exponential at many times in average case.

Below is the implementation of the above approach:
C++
// C++ program to find the ranges of
// consecutive numbers from array
#include <bits/stdc++.h>
using namespace std;
// Function to find consecutive ranges
vector<string> consecutiveRanges(
int nums[], int len)
{
vector<string> res;
// Start with the first element and
// traverse whole of array
for (int i = 0; i < len;) {
// For each continuous integers subarray
// check the first two elements
int j = i + 1;
int l = 1;
// Point of break is either out of bound
// or break of continuous integer range
while (j < len
&& nums[i] + (j - i) == nums[j]) {
// increase the interval/range
// by 2 (exponential)
l *= 2;
j = i + l;
}
// if only one element in range
// directly push in result
if (j - i == 1) {
res.push_back(to_string(nums[i]));
}
else {
// do the linear incremental
// in last half of the interval
j = j - (l / 2);
while (j < len
&& nums[i] + (j - i) == nums[j]) {
j++;
}
// push the range to result
res.push_back(to_string(nums[i]) + "->"
+ to_string(nums[j - 1]));
}
i = j;
}
return res;
}
// Driver Code.
int main()
{
// Test Case 1:
int arr1[] = { 1, 2, 3, 6, 7 };
int n = sizeof(arr1) / sizeof(arr1[0]);
vector<string> ans = consecutiveRanges(arr1, n);
cout << "[";
for (int i = 0; i < ans.size(); i++) {
if (i == ans.size() - 1)
cout << ans[i] << "]" << endl;
else
cout << ans[i] << ", ";
}
// Test Case 2:
int arr2[] = { -1, 0, 1, 2, 5, 6, 8 };
n = sizeof(arr2) / sizeof(arr2[0]);
ans = consecutiveRanges(arr2, n);
cout << "[";
for (int i = 0; i < ans.size(); i++) {
if (i == ans.size() - 1)
cout << ans[i] << "]" << endl;
else
cout << ans[i] << ", ";
}
// Test Case 3:
int arr3[] = { -1, 3, 4, 5, 20, 21, 25 };
n = sizeof(arr3) / sizeof(arr3[0]);
ans = consecutiveRanges(arr3, n);
cout << "[";
for (int i = 0; i < ans.size(); i++) {
if (i == ans.size() - 1)
cout << ans[i] << "]" << endl;
else
cout << ans[i] << ", ";
}
}
Java
// Java program to find the ranges of
// consecutive numbers from array
import java.util.*;
class GFG {
// Function to find consecutive ranges
static List<String> consecutiveRanges(
int[] nums, int len)
{
List<String> res
= new ArrayList<String>();
// Start with the first element and
// traverse whole of array
for (int i = 0; i < len;) {
// For each continuous integers subarray
// check the first two elements
int j = i + 1;
int l = 1;
// Point of break is either out of bound
// or break of continuous integer range
while (j < len
&& nums[i] + (j - i) == nums[j]) {
// increase the interval/range
// by 2 (exponential)
l *= 2;
j = i + l;
}
// if only one element in range
// directly push in result
if (j - i == 1) {
res.add(String.valueOf(nums[i]));
}
else {
// do the linear incremental
// in last half of the interval
j = j - (l / 2);
while (j < len
&& nums[i] + (j - i) == nums[j]) {
j++;
}
// push the range to result
res.add(String.valueOf(nums[i]) + "->"
+ String.valueOf(nums[j - 1]));
}
i = j;
}
return res;
}
// Driver Code.
public static void main(String args[])
{
// Test Case 1:
int[] arr1 = { 1, 2, 3, 6, 7 };
int n = arr1.length;
List<String> ans = new ArrayList<String>();
ans = consecutiveRanges(arr1, n);
System.out.print(ans);
System.out.println();
// Test Case 2:
int[] arr2 = { -1, 0, 1, 2, 5, 6, 8 };
n = arr2.length;
ans = consecutiveRanges(arr2, n);
System.out.print(ans);
System.out.println();
// Test Case 3:
int[] arr3 = { -1, 3, 4, 5, 20, 21, 25 };
n = arr3.length;
ans = consecutiveRanges(arr3, n);
System.out.print(ans);
System.out.println();
}
}
// This code is contributed by pushpeshrajdx01
Python3
## Function to find consecutive ranges
def consecutiveRanges(nums, length):
res = []
## Start with the first element and
## traverse whole of array
i = 0
while i < length:
## For each continuous integers subarray
## check the first two elements
j = i + 1
l = 1
## Point of break is either out of bound
## or break of continuous integer range
while (j < length and ((nums[i] + (j - i)) == nums[j])):
## increase the interval/range
## by 2 (exponential)
l *= 2;
j = i + l;
## if only one element in range
## directly push in result
if (j - i == 1):
res.append(str(nums[i]))
else:
## do the linear incremental
## in last half of the interval
j = j - (l // 2);
while (j < length and ((nums[i] + (j - i)) == nums[j])):
j+=1
## push the range to result
res.append(str(nums[i]) + "->" + str(nums[j - 1]))
i = j
return res
## Driver code
if __name__=='__main__':
## Test Case 1:
arr1 = [1, 2, 3, 6, 7]
n = len(arr1)
ans = consecutiveRanges(arr1, n)
print("[",end='')
for i in range(len(ans)):
if(i==len(ans)-1):
print(ans[i], end='')
print("]")
else:
print(ans[i], end='')
print(", ", end='')
## Test Case 2:
arr2 = [-1, 0, 1, 2, 5, 6, 8]
n = len(arr2)
ans = consecutiveRanges(arr2, n)
print("[",end='')
for i in range(len(ans)):
if(i==len(ans)-1):
print(ans[i], end='')
print("]")
else:
print(ans[i], end='')
print(", ", end='')
## Test Case 3:
arr3 = [-1, 3, 4, 5, 20, 21, 25]
n = len(arr3)
ans = consecutiveRanges(arr3, n)
print("[",end='')
for i in range(len(ans)):
if(i==len(ans)-1):
print(ans[i], end='')
print("]")
else:
print(ans[i], end='')
print(", ", end='')
# This code is contributed by subhamgoyal2014.
C#
// C# program to implement above approach
using System;
using System.Collections.Generic;
class GFG
{
// Function to find consecutive ranges
static List<string> consecutiveRanges(int[] nums, int len)
{
List<string> res = new List<string>();
// Start with the first element and
// traverse whole of array
for (int i = 0 ; i < len ; ) {
// For each continuous integers subarray
// check the first two elements
int j = i + 1;
int l = 1;
// Point of break is either out of bound
// or break of continuous integer range
while (j < len && nums[i] + (j - i) == nums[j]) {
// increase the interval/range
// by 2 (exponential)
l *= 2;
j = i + l;
}
// if only one element in range
// directly push in result
if (j - i == 1) {
res.Add(nums[i].ToString());
}
else {
// do the linear incremental
// in last half of the interval
j = j - (l / 2);
while (j < len
&& nums[i] + (j - i) == nums[j]) {
j++;
}
// push the range to result
res.Add(nums[i].ToString() + "->"
+ nums[j - 1].ToString());
}
i = j;
}
return res;
}
// Driver Code
public static void Main(string[] args)
{
// Test Case 1:
int[] arr1 = { 1, 2, 3, 6, 7 };
int n = arr1.Length;
List<string> ans = consecutiveRanges(arr1, n);
Console.Write("[");
for (int i = 0 ; i < ans.Count ; i++) {
if (i == ans.Count - 1)
Console.Write(ans[i] + "]\n");
else
Console.Write(ans[i] + ", ");
}
// Test Case 2:
int[] arr2 = { -1, 0, 1, 2, 5, 6, 8 };
n = arr2.Length;
ans = consecutiveRanges(arr2, n);
Console.Write("[");
for (int i = 0 ; i < ans.Count ; i++) {
if (i == ans.Count - 1)
Console.Write(ans[i] + "]\n");
else
Console.Write(ans[i] + ", ");
}
// Test Case 3:
int[] arr3 = { -1, 3, 4, 5, 20, 21, 25 };
n = arr3.Length;
ans = consecutiveRanges(arr3, n);
Console.Write("[");
for (int i = 0 ; i < ans.Count ; i++) {
if (i == ans.Count - 1)
Console.Write(ans[i] + "]\n");
else
Console.Write(ans[i] + ", ");
}
}
}
// This code is contributed by entertain2022.
JavaScript
<script>
// JavaScript program to find the ranges of
// consecutive numbers from array
// Function to find consecutive ranges
const consecutiveRanges = (nums, len) => {
let res = [];
// Start with the first element and
// traverse whole of array
for (let i = 0; i < len;) {
// For each continuous integers subarray
// check the first two elements
let j = i + 1;
let l = 1;
// Point of break is either out of bound
// or break of continuous integer range
while (j < len
&& nums[i] + (j - i) == nums[j]) {
// increase the interval/range
// by 2 (exponential)
l *= 2;
j = i + l;
}
// if only one element in range
// directly push in result
if (j - i == 1) {
res.push(nums[i].toString());
}
else {
// do the linear incremental
// in last half of the interval
j = j - (l / 2);
while (j < len
&& nums[i] + (j - i) == nums[j]) {
j++;
}
// push the range to result
res.push(nums[i].toString() + "->" + nums[j - 1].toString());
}
i = j;
}
return res;
}
// Driver Code.
// Test Case 1:
let arr1 = [1, 2, 3, 6, 7];
let n = arr1.length;
let ans = consecutiveRanges(arr1, n);
document.write("[");
for (let i = 0; i < ans.length; i++) {
if (i == ans.length - 1)
document.write(`${ans[i]}]<br/>`);
else
document.write(`${ans[i]}, `);
}
// Test Case 2:
let arr2 = [-1, 0, 1, 2, 5, 6, 8];
n = arr2.length;
ans = consecutiveRanges(arr2, n);
document.write("[");
for (let i = 0; i < ans.length; i++) {
if (i == ans.length - 1)
document.write(`${ans[i]}]<br/>`);
else
document.write(`${ans[i]}, `);
}
// Test Case 3:
let arr3 = [-1, 3, 4, 5, 20, 21, 25];
n = arr3.length;
ans = consecutiveRanges(arr3, n);
document.write("[");
for (let i = 0; i < ans.length; i++) {
if (i == ans.length - 1)
document.write(`${ans[i]}]<br/>`);
else
document.write(`${ans[i]}, `);
}
// This code is contributed by rakeshsahni
</script>
Output[1->3, 6->7]
[-1->2, 5->6, 8]
[-1, 3->5, 20->21, 25]
Time complexity:
Worst Case: O(N)
Average Case: O(log N)
Best Base: O(log N)
Auxiliary Space: O(N)
Similar Reads
Find all ranges of consecutive numbers from Array Given a sorted array arr[] consisting of N integers without any duplicates, the task is to find the ranges of consecutive numbers from that array.Examples: Input: arr[] = {1, 2, 3, 6, 7} Output: 1->3, 6->7 Explanation: There are two ranges of consecutive number from that array. Range 1 = 1 -
10 min read
Query to check if a range is made up of consecutive elements Given an array of n non-consecutive integers and Q queries, the task is to check whether for the given range l and r, the elements are consecutive or not.Examples: Input: arr = { 2, 4, 3, 7, 6, 1}, Q = { (1, 3), (3, 5), (5, 6) } Output: Yes, No, No Explanation: Array elements from (1, 3) = {2, 4, 3}
15 min read
Find elements of array using XOR of consecutive elements Given an array arr[] in which XOR of every 2 consecutive elements of the original array is given i.e if the total number of elements in the original array is n then the size of this XOR array would be n-1. The first element in the original array is also given. The task is to find out the rest of n-1
8 min read
Smallest list of ranges that includes all the numbers which are not in array Given a range [l, r] and an array arr[] of unique integers and l <= arr[i] <= r. The task is to find the smallest list of ranges that includes all the numbers that are not in the given array within a certain range. Example: Input: arr = {3, 5, 10, 11, 12, 15} , l = 1, h = 20Output: {1, 2} {4,
9 min read
Sum of minimum difference between consecutive elements of an array Given an array of pairs where each pair represents a range, the task is to find the sum of the minimum difference between the consecutive elements of an array where the array is filled in the below manner: Each element of an array lies in the range given at its corresponding index in the range array
10 min read