GFG App
Open App
Browser
Continue

# Find all ranges of consecutive numbers from Array | Set -2 (using Exponential BackOff)

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 ` `using` `namespace` `std;`   `// Function to find consecutive ranges` `vector consecutiveRanges(` `    ``int` `nums[], ``int` `len)` `{` `    ``vector 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 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 consecutiveRanges(` `    ``int``[] nums, ``int` `len)` `{` `    ``List res` `            ``= ``new` `ArrayList();` ` `  `    ``// 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 ans = ``new` `ArrayList();` `        ``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

 ``

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)

My Personal Notes arrow_drop_up