Talentd
FleetCode
Make and follow sheets.Sign in

Summary Ranges solution and explanation

EasyArray5 min read54.6% acceptanceUpdated 9 Apr 2026
Summary Ranges - Leetcode 228 - Arrays & Strings (Python)Greg Hogg · 5:57 · 31K viewsWatch on YouTube
9 more videos on this problem
  1. Summary Ranges - Leetcode 228 - Arrays & Strings (Python)Greg Hogg · 5:57 · 31K views
  2. Summary Ranges | Leetcode-228 | GOOGLE | Explanation ➕ Live CodingcodestorywithMIK · 13:04 · 10K views
  3. Summary Ranges | summary ranges | summary ranges leetcode | leetcode 228 | linearNaresh Gupta · 6:22 · 10K views
  4. Leetcode - Summary Ranges (Python)Timothy H Chang · 5:03 · 4K views
  5. Summary Ranges | Leet code 228 | Theory explained + Python codeSai Anish Malla · 11:15 · 2K views
  6. Summary Ranges | LeetCode 228 | Solution Walkthrough - PythonTech and Navid · 13:52 · 1K views
  7. Summary Ranges - 228. LeetCode - JavaTeddy Smith · 10:30 · 1K views
  8. Summary Ranges | LeetCode 228 | October LeetCode Challenge | Day 28Learn Code Repeat · 8:14 · 605 views
  9. Leetcode 228 - Summary Ranges - Python SolutionData Engineering Studies · 8:36 · 413 views
  10. LeetCode 228. [easy] Summary RangesFrancesco Manicardi · 5:05 · 352 views

The problem

You are given a sorted unique integer array nums.

A range [a,b] is the set of all integers from a to b (inclusive).

Return the smallest sorted list of ranges that cover all the numbers in the array exactly. That is, each element of nums is covered by exactly one of the ranges, and there is no integer x such that x is in one of the ranges but not in nums.

Each range [a,b] in the list should be output as:

  • "a->b" if a != b
  • "a" if a == b

Example 1:

Input: nums = [0,1,2,4,5,7]
Output: ["0->2","4->5","7"]
Explanation: The ranges are:
[0,2] --> "0->2"
[4,5] --> "4->5"
[7,7] --> "7"

Example 2:

Input: nums = [0,2,3,4,6,8,9]
Output: ["0","2->4","6","8->9"]
Explanation: The ranges are:
[0,0] --> "0"
[2,4] --> "2->4"
[6,6] --> "6"
[8,9] --> "8->9"

Constraints:

  • 0 <= nums.length <= 20
  • -231 <= nums[i] <= 231 - 1
  • All the values of nums are unique.
  • nums is sorted in ascending order.

Approach overview

Problem Overview: You receive a sorted array of unique integers. The goal is to compress consecutive numbers into range strings. A single number becomes "x", while a sequence like 1,2,3 becomes "1->3". The result is a list of ranges covering the entire array.

The key observation: because the array is sorted and contains no duplicates, consecutive numbers always appear next to each other. The problem reduces to detecting where a sequence starts and where it breaks.

Approach 1: Sequential Range Detection (O(n) time, O(1) space)

Iterate through the array while tracking the start of the current range. For each element, check whether the next number continues the sequence using nums[i] + 1 == nums[i+1]. When this condition fails, the range ends. If the start and end indices are the same, output a single value string; otherwise output start->end. Then reset the start pointer to the next element and continue scanning.

This approach works because every element belongs to exactly one range, so the array only needs a single pass. No additional data structures are required. It’s straightforward and highly readable, making it a common baseline implementation.

Approach 2: Optimal Pointer Movement (O(n) time, O(1) space)

This method uses a two‑pointer style scan. One pointer marks the beginning of a range, while the other pointer advances forward as long as numbers remain consecutive. When the sequence breaks, the interval between the two pointers forms a valid range. Format the result and move the start pointer to the next unexplored position.

The difference from the previous approach is that the forward pointer aggressively expands the range before producing output. Each element is still visited once, giving linear time complexity. Because only a few index variables are used, the space complexity remains constant.

This pattern appears often in problems involving sorted arrays and interval compression. Similar pointer movement techniques show up in problems involving array traversal and range grouping.

Recommended for interviews: Interviewers expect the linear scan solution. Either sequential detection or two‑pointer expansion demonstrates the same key insight: detect boundaries where consecutive numbers stop. A brute force or nested scan would signal missed optimization opportunities, while the O(n) approach shows you recognize sorted array structure and exploit it efficiently.

Approach 1: Sequential Range Detection

This approach involves detecting the start and end of each range by iterating through the array sequentially. You remember the start of a potential range and adjust the range's end as long as consecutive numbers are found. When a break in consecutiveness occurs, you fix the end of the current range and start a new one.


from typing import List

def summaryRanges(nums: List[int]) -> List[str]:
    ranges = []
    i = 0
    while i < len(nums):
        start = i
        while i + 1 < len(nums) and nums[i] + 1 == nums[i + 1]:
            i += 1
        if start == i:
            ranges.append(str(nums[start]))
        else:
            ranges.append(f"{nums[start]}->{nums[i]}")
        i += 1
    return ranges

import java.util.ArrayList;
import java.util.List;

public class Solution {
    public List<String> summaryRanges(int[] nums) {
        List<String> result = new ArrayList<>();
        int i = 0;
        while (i < nums.length) {
            int start = i;
            while (i + 1 < nums.length && nums[i] + 1 == nums[i + 1]) { 
                i++;
            }
            if (start == i) {
                result.add(String.valueOf(nums[start]));
            } else {
                result.add(nums[start] + "->" + nums[i]);
            }
            i++;
        }
        return result;
    }
}

#include <vector>
#include <string>

using namespace std;

vector<string> summaryRanges(vector<int>& nums) {
    vector<string> result;
    int n = nums.size();
    int i = 0;
    while (i < n) {
        int start = i;
        while (i + 1 < n && nums[i] + 1 == nums[i + 1]) {
            i++;
        }
        if (start == i) {
            result.push_back(to_string(nums[start]));
        } else {
            result.push_back(to_string(nums[start]) + "->" + to_string(nums[i]));
        }
        i++;
    }
    return result;
}

function summaryRanges(nums) {
    const result = [];
    let i = 0;
    while (i < nums.length) {
        let start = i;
        while (i + 1 < nums.length && nums[i] + 1 === nums[i + 1]) {
            i++;
        }
        if (start === i) {
            result.push(`${nums[start]}`);
        } else {
            result.push(`${nums[start]}->${nums[i]}`);
        }
        i++;
    }
    return result;
}

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

char** summaryRanges(int* nums, int numsSize, int* returnSize) {
    char **result = (char **)malloc(numsSize * sizeof(char *));
    *returnSize = 0;
    int i = 0;
    while (i < numsSize) {
        int start = i;
        while (i + 1 < numsSize && nums[i] + 1 == nums[i + 1]) {
            i++;
        }
        int end = i;
        char *range = (char *)malloc(25 * sizeof(char));
        if (start == end) {
            sprintf(range, "%d", nums[start]);
        } else {
            sprintf(range, "%d->%d", nums[start], nums[end]);
        }
        result[(*returnSize)++] = range;
        i++;
    }
    return result;
}

using System;
using System.Collections.Generic;

public class Solution {
    public IList<string> SummaryRanges(int[] nums) {
        List<string> result = new List<string>();
        int i = 0;
        while (i < nums.Length) {
            int start = i;
            while (i + 1 < nums.Length && nums[i] + 1 == nums[i + 1]) {
                i++;
            }
            if (start == i) {
                result.Add(nums[start].ToString());
            } else {
                result.Add(nums[start] + "->" + nums[i]);
            }
            i++;
        }
        return result;
    }
}

Python uses a straightforward looping structure to find ranges. It uses format strings to easily concatenate numbers for ranges needing a '->'. This solution appends directly to list using range or single-potential numbers.

Complexity

Time Complexity: O(n)
Space Complexity: O(n)

Try this approach in the editor

Approach 2: Optimal Pointer Movement

This approach utilizes a two-pointer method where one pointer marks the beginning of a new range, and another pointer (or the loop index itself) expands the range as far as possible until the next number isn't consecutive. Once a sequence ends, if numbers are the same, it is a single-element range; otherwise, a range connecting two different numbers is formed.


from typing import List

def summaryRanges(nums: List[int]) -> List[str]:
    ranges = []
    i = 0
    while i < len(nums):
        start = i
        j = i
        while j + 1 < len(nums) and nums[j] + 1 == nums[j + 1]:
            j += 1
        if start == j:
            ranges.append(str(nums[start]))
        else:
            ranges.append(f"{nums[start]}->{nums[j]}")
        i = j + 1
    return ranges

import java.util.ArrayList;
import java.util.List;

public class Solution {
    public List<String> summaryRanges(int[] nums) {
        List<String> result = new ArrayList<>();
        int i = 0;
        while (i < nums.length) {
            int start = i;
            int j = i;
            while (j + 1 < nums.length && nums[j] + 1 == nums[j + 1]) {
                j++;
            }
            if (start == j) {
                result.add(String.valueOf(nums[start]));
            } else {
                result.add(nums[start] + "->" + nums[j]);
            }
            i = j + 1;
        }
        return result;
    }
}

#include <vector>
#include <string>

using namespace std;

vector<string> summaryRanges(vector<int>& nums) {
    vector<string> result;
    int n = nums.size();
    int i = 0;
    while (i < n) {
        int start = i;
        int j = i;
        while (j + 1 < n && nums[j] + 1 == nums[j + 1]) {
            j++;
        }
        if (start == j) {
            result.push_back(to_string(nums[start]));
        } else {
            result.push_back(to_string(nums[start]) + "->" + to_string(nums[j]));
        }
        i = j + 1;
    }
    return result;
}

function summaryRanges(nums) {
    const result = [];
    let i = 0;
    while (i < nums.length) {
        let start = i;
        let j = i;
        while (j + 1 < nums.length && nums[j] + 1 === nums[j + 1]) {
            j++;
        }
        if (start === j) {
            result.push(`${nums[start]}`);
        } else {
            result.push(`${nums[start]}->${nums[j]}`);
        }
        i = j + 1;
    }
    return result;
}

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

char** summaryRanges(int* nums, int numsSize, int* returnSize) {
    char **result = (char **)malloc(numsSize * sizeof(char *));
    *returnSize = 0;
    int i = 0;
    while (i < numsSize) {
        int start = i;
        while (i + 1 < numsSize && nums[i] + 1 == nums[i + 1]) {
            i++;
        }
        int end = i;
        char *range = (char *)malloc(25 * sizeof(char));
        if (start == end) {
            sprintf(range, "%d", nums[start]);
        } else {
            sprintf(range, "%d->%d", nums[start], nums[end]);
        }
        result[(*returnSize)++] = range;
        i++;
    }
    return result;
}

using System;
using System.Collections.Generic;

public class Solution {
    public IList<string> SummaryRanges(int[] nums) {
        List<string> result = new List<string>();
        int i = 0;
        while (i < nums.Length) {
            int start = i;
            int j = i;
            while (j + 1 < nums.Length && nums[j] + 1 == nums[j + 1]) {
                j++;
            }
            if (start == j) {
                result.Add(nums[start].ToString());
            } else {
                result.Add(nums[start] + "->" + nums[j]);
            }
            i = j + 1;
        }
        return result;
    }
}

Python uses nested loops to manage two pointers, 'i' and 'j', determining where ranges start and extend until consecutive integers break. Then, constructs string format to reflect the range.

Complexity

Time Complexity: O(n)
Space Complexity: O(n)

Try this approach in the editor

Approach 3: Two Pointers

We can use two pointers i and j to find the left and right endpoints of each interval.

Traverse the array, when j + 1 < n and nums[j + 1] = nums[j] + 1, move j to the right, otherwise the interval [i, j] has been found, add it to the answer, then move i to the position of j + 1, and continue to find the next interval.

Time complexity O(n), where n is the length of the array. Space complexity O(1).

function summaryRanges(nums: number[]): string[] {
    const f = (i: number, j: number): string => {
        return i === j ? `${nums[i]}` : `${nums[i]}->${nums[j]}`;
    };
    const n = nums.length;
    const ans: string[] = [];
    for (let i = 0, j = 0; i < n; i = j + 1) {
        j = i;
        while (j + 1 < n && nums[j + 1] === nums[j] + 1) {
            ++j;
        }
        ans.push(f(i, j));
    }
    return ans;
}
func summaryRanges(nums []int) (ans []string) {
	f := func(i, j int) string {
		if i == j {
			return strconv.Itoa(nums[i])
		}
		return strconv.Itoa(nums[i]) + "->" + strconv.Itoa(nums[j])
	}
	for i, j, n := 0, 0, len(nums); i < n; i = j + 1 {
		j = i
		for j+1 < n && nums[j+1] == nums[j]+1 {
			j++
		}
		ans = append(ans, f(i, j))
	}
	return
}
impl Solution {
    #[allow(dead_code)]
    pub fn summary_ranges(nums: Vec<i32>) -> Vec<String> {
        if nums.is_empty() {
            return vec![];
        }

        let mut ret = Vec::new();
        let mut start = nums[0];
        let mut prev = nums[0];
        let mut current = 0;
        let n = nums.len();

        for i in 1..n {
            current = nums[i];
            if current != prev + 1 {
                if start == prev {
                    ret.push(start.to_string());
                } else {
                    ret.push(start.to_string() + "->" + &prev.to_string());
                }
                start = current;
                prev = current;
            } else {
                prev = current;
            }
        }

        if start == prev {
            ret.push(start.to_string());
        } else {
            ret.push(start.to_string() + "->" + &prev.to_string());
        }

        ret
    }
}
Try this approach in the editor

Complexity comparison

ApproachComplexity
Sequential Range Detection

Time Complexity: O(n)
Space Complexity: O(n)

Optimal Pointer Movement

Time Complexity: O(n)
Space Complexity: O(n)

Two Pointers–

Complexity analysis

ApproachTimeSpaceWhen to Use
Sequential Range DetectionO(n)O(1)Simple single-pass scan when array is already sorted and you want the most readable implementation
Optimal Pointer MovementO(n)O(1)When using two-pointer range expansion patterns common in sorted array and interval problems

Frequently asked questions

Is Summary Ranges easy or hard?

Summary Ranges is categorized as an Easy problem on LeetCode. The challenge mainly involves correctly detecting consecutive sequences and formatting the output ranges. Once you recognize that a single pass over the sorted array is sufficient, the implementation becomes straightforward.

How to solve Summary Ranges in O(n)?

Traverse the array while tracking the start of the current range. Continue moving forward while consecutive numbers satisfy nums[i] + 1 == nums[i+1]. When the sequence stops, output the range and reset the start pointer. Because every element is processed once, the algorithm runs in linear time.

What is the best approach for Summary Ranges?

The optimal approach is a linear scan that detects boundaries of consecutive numbers. Track the start of a range and continue advancing while numbers remain consecutive. Once the sequence breaks, format the range as either a single number or "start->end". This solution runs in O(n) time and O(1) space.

What data structure is used in Summary Ranges?

The problem primarily uses arrays and simple index variables. No advanced data structures such as hash maps or stacks are required. The logic relies on sequential traversal and detecting boundaries between consecutive values.

What is the time complexity of Summary Ranges?

The standard solution runs in O(n) time because each element in the sorted array is visited exactly once during the scan. No nested loops are required. Space complexity is O(1) excluding the output list since only a few index variables are maintained.

Summary Ranges Python or Java solution approach?

In Python or Java, the typical implementation iterates through the array while tracking the start index of a range. When the next value is not consecutive, the range is formatted and appended to the result list. The same O(n) time and O(1) extra space complexity applies across languages.

Is Summary Ranges asked at Google, Amazon, or Meta?

Summary Ranges is a classic array scanning problem commonly used in coding interviews to test iteration logic and handling of ranges. Variations of range compression and interval grouping appear in interviews at companies like Amazon and Meta, especially in early technical screens.

Comments

Now write it yourselfClose this page and solve Summary Ranges in the editor, without looking.
Practise Summary Ranges