Last Updated: March 29, 2026
We have a sorted array of unique integers, and we need to compress it into a list of ranges. Consecutive numbers get grouped into a single range like "a->b", while isolated numbers stand alone as "a".
The key insight is that because the array is already sorted and unique, consecutive numbers will always appear next to each other. So if nums[i+1] == nums[i] + 1, those two belong in the same range. The moment that relationship breaks, we know the current range has ended and a new one begins.
This is fundamentally a grouping problem: scan through the array, identify where consecutive sequences start and end, and format each group as a string.
0 <= nums.length <= 20 - With at most 20 elements, any approach works. The focus is entirely on correctness and clean logic.-2^31 <= nums[i] <= 2^31 - 1 - Values span the full 32-bit signed integer range. Be careful with arithmetic like nums[i] + 1, which could overflow in languages with fixed-width integers.nums is sorted and unique - No need to sort or deduplicate. We can rely on the ordering for a single linear pass.The most natural way to think about this: walk through the array, and every time you find a break in the consecutive sequence, record the range you just finished.
Start by remembering the index where the current range begins. Then keep advancing as long as the next number is exactly one more than the current. When you hit a gap (or reach the end of the array), the range from the start index to the current index is complete. Format it and move on.
i = 0 as the starting index.i < n: a. Record start = nums[i] as the beginning of a new range.
b. While i + 1 < n and nums[i + 1] == nums[i] + 1, advance i.
c. Now nums[i] is the end of the current range.
d. If start == nums[i], add "start" to the result. Otherwise, add "start->nums[i]".
e. Advance i to the next unprocessed element.
i, so the total number of iterations across both loops is n.i, start). The output list does not count toward auxiliary space.Both approaches are already optimal at O(n). The alternative below uses a for loop instead of a while loop, which some people find slightly cleaner.
Instead of using a while loop with manual index management, we can use a cleaner two-pointer pattern. Keep a start pointer that marks where the current range begins, and use the loop variable as the end pointer. Every time we detect that the next element breaks the consecutive sequence (or we have reached the last element), we know the range from start to the current index is complete.
The idea is the same as Approach 1, but the code structure is slightly different. Some people find this version easier to read because the for loop handles the iteration, and we only need to track when to "close" a range.
The sorted and unique properties of the array guarantee that consecutive integers will appear in adjacent positions. So the question reduces to: "where do the consecutive runs start and end?" By advancing a pointer as long as the next value is exactly one more, we find each run's endpoint. The formatting step at the end of each run is just a simple comparison.
i from 0 to n-1.start = nums[i] as the beginning of the current range.i + 1 < n and nums[i + 1] == nums[i] + 1, advance i.start == nums[i], add the single number. Otherwise, add "start->nums[i]".