Talentd
FleetCode
Make and follow sheets.Sign in

Positions of Large Groups solution and explanation

EasyString5 min read54.4% acceptanceUpdated 9 Apr 2026
830. Positions of Large Groups | LEETCODE SOLUTION | EASYcode Explainer · 5:18 · 718 viewsWatch on YouTube
8 more videos on this problem
  1. 830. Positions of Large Groups | LEETCODE SOLUTION | EASYcode Explainer · 5:18 · 718 views
  2. Leetcode solving: 830. Positions of Large GroupsMath Geeks · 3:29 · 420 views
  3. Vol142 - Leetcode - Problem 830 - Positions of large groups - Golang - Phỏng vấn - Thuật toánYuh lập trình viên · 9:01 · 191 views
  4. LeetCode 830 | Positions of Large Groups | 2 Pointers| JavaSleepy Cracker · 6:09 · 189 views
  5. 830 Positions of Large GroupsHundred Coding · 11:19 · 147 views
  6. No Sound Leetcode 830: Positions of Large GroupsExtremeProgrammer · 1:01 · 51 views
  7. Day 671: LeetCode Problem 830. Positions of Large Groups - SwiftiOSxBank · 10:37 · 31 views
  8. LeetCode 830 Positions of Large Groups 🔍 Two Pointers Explained 💡 Day 10 | 51/1000 DSA Journey 🔥leetcode Grind · 2:45 · 11 views
  9. LeetCode 830: Positions of Large GroupsAlitaCode · 25:09 · 6 views

The problem

In a string s of lowercase letters, these letters form consecutive groups of the same character.

For example, a string like s = "abbxxxxzyy" has the groups "a", "bb", "xxxx", "z", and "yy".

A group is identified by an interval [start, end], where start and end denote the start and end indices (inclusive) of the group. In the above example, "xxxx" has the interval [3,6].

A group is considered large if it has 3 or more characters.

Return the intervals of every large group sorted in increasing order by start index.

Example 1:

Input: s = "abbxxxxzzy"
Output: [[3,6]]
Explanation: "xxxx" is the only large group with start index 3 and end index 6.

Example 2:

Input: s = "abc"
Output: []
Explanation: We have groups "a", "b", and "c", none of which are large groups.

Example 3:

Input: s = "abcdddeeeeaabbbcd"
Output: [[3,5],[6,9],[12,14]]
Explanation: The large groups are "ddd", "eeee", and "bbb".

Constraints:

  • 1 <= s.length <= 1000
  • s contains lowercase English letters only.

Approach overview

Problem Overview: Given a string s, you need to return the start and end indices of every group of identical characters that appears three or more times consecutively. These are called large groups. The result should list each group's starting and ending index in ascending order.

Approach 1: Iterative Group Detection (O(n) time, O(1) space)

This approach scans the string once while tracking the start index of the current character group. Iterate through the string and compare each character with the previous one. When the character changes, the current group ends. Check the group length using i - start; if it is at least 3, record [start, i-1]. Then update start to the current index and continue scanning. After the loop, run the same check for the final group since it might reach the end of the string. The algorithm performs a single pass over the string, giving O(n) time complexity and constant O(1) extra space (excluding the output). This method works well for problems involving consecutive patterns in a string.

Approach 2: Two Pointer Technique (O(n) time, O(1) space)

The two pointers pattern provides a clean way to track character groups. Maintain two indices: left marks the start of a group and right expands forward while characters remain the same. While s[right] == s[left], keep moving right. Once a different character appears or the string ends, compute the group size using right - left. If the size is at least 3, append [left, right-1] to the result. Then move left to right to begin scanning the next group. Each character is visited at most twice (once by each pointer), so the time complexity remains O(n) with O(1) additional space. This version clearly separates group detection and expansion logic, which many engineers find easier to reason about.

Recommended for interviews: Interviewers typically expect the linear scan or two-pointer solution because both run in O(n) time and require only constant extra space. Starting with the iterative group detection approach shows you understand how to track contiguous segments in a string. Implementing the two-pointer variation demonstrates familiarity with a widely used pattern for segment scanning problems.

Approach 1: Iterative Group Detection

This approach involves iterating through the string to detect groups of consecutive characters. We maintain a start index for the current group and check whenever a character changes. If the length of a group is 3 or more, we record the start and end indices.


def large_group_positions(s):
    result = []
    start = 0
    for i in range(1, len(s) + 1):
        if i == len(s) or s[i] != s[start]:
            if i - start >= 3:
                result.append([start, i - 1])
            start = i
    return result

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

public class Solution {
    public List<List<Integer>> largeGroupPositions(String s) {
        List<List<Integer>> result = new ArrayList<>();
        int start = 0, n = s.length();
        for (int i = 1; i <= n; ++i) {
            if (i == n || s.charAt(i) != s.charAt(start)) {
                if (i - start >= 3) {
                    result.add(List.of(start, i - 1));
                }
                start = i;
            }
        }
        return result;
    }
}

#include <vector>
#include <string>
using namespace std;

vector<vector<int>> largeGroupPositions(string s) {
    vector<vector<int>> result;
    int start = 0, n = s.size();
    for (int i = 1; i <= n; ++i) {
        if (i == n || s[i] != s[start]) {
            if (i - start >= 3) {
                result.push_back({start, i - 1});
            }
            start = i;
        }
    }
    return result;
}

function largeGroupPositions(s) {
    const result = [];
    let start = 0;
    for (let i = 1; i <= s.length; i++) {
        if (i === s.length || s[i] !== s[start]) {
            if (i - start >= 3) {
                result.push([start, i - 1]);
            }
            start = i;
        }
    }
    return result;
}

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

int** largeGroupPositions(char* s, int* returnSize, int** returnColumnSizes) {
    int n = strlen(s);
    int** result = (int**)malloc(n * sizeof(int*));
    *returnColumnSizes = (int*)malloc(n * sizeof(int));
    *returnSize = 0;
    int start = 0;
    for (int i = 1; i <= n; i++) {
        if (i == n || s[i] != s[start]) {
            if (i - start >= 3) {
                result[*returnSize] = (int*)malloc(2 * sizeof(int));
                result[*returnSize][0] = start;
                result[*returnSize][1] = i - 1;
                (*returnColumnSizes)[*returnSize] = 2;
                (*returnSize)++;
            }
            start = i;
        }
    }
    return result;
}

using System;
using System.Collections.Generic;

public class Solution {
    public IList<IList<int>> LargeGroupPositions(string s) {
        List<IList<int>> result = new List<IList<int>>();
        int start = 0;
        for (int i = 1; i <= s.Length; i++) {
            if (i == s.Length || s[i] != s[start]) {
                if (i - start >= 3) {
                    result.Add(new List<int> { start, i - 1 });
                }
                start = i;
            }
        }
        return result;
    }
}

In this Python solution, we utilize list operations to determine the start and end of each group. If a group is determined to be large, its indices are appended to the result list.

Complexity

Time Complexity: O(n), where n is the length of the string.
Space Complexity: O(n) for storing the result.

Try this approach in the editor

Approach 2: Two Pointer Technique

The two-pointer technique is another efficient way to solve this problem. The idea is to have a slow pointer marking the start of the group and a fast pointer iterating through the string. When the character at the fast pointer changes or reaches the end, check the length of the group.


def large_group_positions(s):
    result = []
    slow = 0
    for fast in range(len(s)):
        if fast == len(s) - 1 or s[fast] != s[fast + 1]:
            if fast - slow + 1 >= 3:
                result.append([slow, fast])
            slow = fast + 1
    return result

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

public class Solution {
    public List<List<Integer>> largeGroupPositions(String s) {
        List<List<Integer>> result = new ArrayList<>();
        int slow = 0, n = s.length();
        for (int fast = 0; fast < n; ++fast) {
            if (fast == n - 1 || s.charAt(fast) != s.charAt(fast + 1)) {
                if (fast - slow + 1 >= 3) {
                    result.add(List.of(slow, fast));
                }
                slow = fast + 1;
            }
        }
        return result;
    }
}

#include <vector>
#include <string>
using namespace std;

vector<vector<int>> largeGroupPositions(string s) {
    vector<vector<int>> result;
    int n = s.size(), slow = 0;
    for (int fast = 0; fast < n; ++fast) {
        if (fast == n - 1 || s[fast] != s[fast + 1]) {
            if (fast - slow + 1 >= 3) {
                result.push_back({slow, fast});
            }
            slow = fast + 1;
        }
    }
    return result;
}

function largeGroupPositions(s) {
    const result = [];
    let slow = 0;
    for (let fast = 0; fast < s.length; fast++) {
        if (fast === s.length - 1 || s[fast] !== s[fast + 1]) {
            if (fast - slow + 1 >= 3) {
                result.push([slow, fast]);
            }
            slow = fast + 1;
        }
    }
    return result;
}

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

int** largeGroupPositions(char* s, int* returnSize, int** returnColumnSizes) {
    int n = strlen(s), slow = 0;
    int** result = (int**)malloc(n * sizeof(int*));
    *returnColumnSizes = (int*)malloc(n * sizeof(int));
    *returnSize = 0;
    for (int fast = 0; fast < n; fast++) {
        if (fast == n - 1 || s[fast] != s[fast + 1]) {
            if (fast - slow + 1 >= 3) {
                result[*returnSize] = (int*)malloc(2 * sizeof(int));
                result[*returnSize][0] = slow;
                result[*returnSize][1] = fast;
                (*returnColumnSizes)[*returnSize] = 2;
                (*returnSize)++;
            }
            slow = fast + 1;
        }
    }
    return result;
}

using System;
using System.Collections.Generic;

public class Solution {
    public IList<IList<int>> LargeGroupPositions(string s) {
        List<IList<int>> result = new List<IList<int>>();
        int slow = 0;
        for (int fast = 0; fast < s.Length; fast++) {
            if (fast == s.Length - 1 || s[fast] != s[fast + 1]) {
                if (fast - slow + 1 >= 3) {
                    result.Add(new List<int> { slow, fast });
                }
                slow = fast + 1;
            }
        }
        return result;
    }
}

The Python solution uses a loop with two variables representing `slow` and `fast` pointers. As `fast` checks each character, changes or end conditions trigger evaluations.

Complexity

Time Complexity: O(n), where n is the length of the string.
Space Complexity: O(n) for storing the result.

Try this approach in the editor

Approach 3: Two Pointers

We use two pointers i and j to find the start and end positions of each group, then check if the group length is greater than or equal to 3. If so, we add it to the result array.

The time complexity is O(n), where n is the length of the string s.

function largeGroupPositions(s: string): number[][] {
    const n = s.length;
    const ans: number[][] = [];

    for (let i = 0; i < n; ) {
        let j = i;
        while (j < n && s[j] === s[i]) {
            ++j;
        }
        if (j - i >= 3) {
            ans.push([i, j - 1]);
        }
        i = j;
    }

    return ans;
}
func largeGroupPositions(s string) [][]int {
	i, n := 0, len(s)
	ans := [][]int{}
	for i < n {
		j := i
		for j < n && s[j] == s[i] {
			j++
		}
		if j-i >= 3 {
			ans = append(ans, []int{i, j - 1})
		}
		i = j
	}
	return ans
}
Try this approach in the editor

Complexity comparison

ApproachComplexity
Iterative Group Detection

Time Complexity: O(n), where n is the length of the string.
Space Complexity: O(n) for storing the result.

Two Pointer Technique

Time Complexity: O(n), where n is the length of the string.
Space Complexity: O(n) for storing the result.

Two Pointers–

Complexity analysis

ApproachTimeSpaceWhen to Use
Iterative Group DetectionO(n)O(1)Simple implementation when scanning consecutive characters in a string
Two Pointer TechniqueO(n)O(1)Preferred when solving segment or range problems using expanding windows

Frequently asked questions

Is Positions of Large Groups easy or hard?

Positions of Large Groups is classified as an Easy problem on LeetCode. The challenge mainly involves recognizing consecutive character groups and tracking their boundaries correctly while scanning the string once.

Positions of Large Groups Python/Java solution

In both Python and Java, the solution typically uses a loop or two pointers to track consecutive characters. When a group's length reaches three or more, append the start and end indices to a list. The implementation remains O(n) time and O(1) additional space aside from the result.

How to solve Positions of Large Groups in O(n)?

Scan the string while tracking the start index of each group of identical characters. When the character changes, compute the group length using the difference between the current index and the start index. If the length is at least three, store the start and end indices. Continue this process until the end of the string.

What is the best approach for Positions of Large Groups?

The best approach is a linear scan using either iterative group detection or the two pointer technique. Both methods traverse the string once and track consecutive characters to identify groups of length three or more. This results in O(n) time complexity and O(1) extra space, which is optimal for this problem.

Is Positions of Large Groups asked at Google/Amazon/Meta?

Positions of Large Groups is a common entry-level string problem used in coding interviews and practice platforms like LeetCode. While it is easier than typical Google or Meta interview questions, it tests understanding of string traversal and two-pointer techniques that frequently appear in interviews.

What data structure is used in Positions of Large Groups?

The problem primarily uses basic string traversal with index variables. No advanced data structures are required. The algorithm relies on tracking indices and storing qualifying ranges in a result list or array.

What is the time complexity of Positions of Large Groups?

The optimal solution runs in O(n) time where n is the length of the string. Each character is processed at most once while scanning for consecutive groups. The space complexity is O(1) because only a few index variables are maintained besides the output list.

Comments

Now write it yourselfClose this page and solve Positions of Large Groups in the editor, without looking.
Practise Positions of Large Groups