#2213

Longest Substring of One Repeating Character

Hard
ArrayStringSegment TreeOrdered SetSegment TreeDynamic Programming
LeetCode ↗

Approaches

Brute ForceOptimal
Complexity Comparison
Brute ForceOptimal Solution
Time
O(n²)
O(log n)
Space
O(1)
O(n)
💡

Intuition

Time O(log n)Space O(n)

Using a segment tree allows us to efficiently update the string and query the longest substring of repeating characters in logarithmic time, making it suitable for multiple updates.

⚙️

Algorithm

3 steps
  1. 1Step 1: Build a segment tree where each node stores the length of the longest substring of repeating characters for that segment.
  2. 2Step 2: For each query, update the character in the string and update the corresponding segment tree nodes.
  3. 3Step 3: After each update, query the segment tree to get the longest substring length.
solution.py43 lines
1class SegmentTree:
2    def __init__(self, s):
3        self.n = len(s)
4        self.tree = [0] * (4 * self.n)
5        self.build(s, 0, 0, self.n - 1)
6
7    def build(self, s, node, start, end):
8        if start == end:
9            self.tree[node] = 1
10        else:
11            mid = (start + end) // 2
12            self.build(s, 2 * node + 1, start, mid)
13            self.build(s, 2 * node + 2, mid + 1, end)
14            self.tree[node] = max(self.tree[2 * node + 1], self.tree[2 * node + 2])
15
16    def update(self, idx, value, node, start, end):
17        if start == end:
18            self.tree[node] = value
19        else:
20            mid = (start + end) // 2
21            if start <= idx <= mid:
22                self.update(idx, value, 2 * node + 1, start, mid)
23            else:
24                self.update(idx, value, 2 * node + 2, mid + 1, end)
25            self.tree[node] = max(self.tree[2 * node + 1], self.tree[2 * node + 2])
26
27    def query(self, L, R, node, start, end):
28        if R < start or end < L:
29            return 0
30        if L <= start and end <= R:
31            return self.tree[node]
32        mid = (start + end) // 2
33        left_query = self.query(L, R, 2 * node + 1, start, mid)
34        right_query = self.query(L, R, 2 * node + 2, mid + 1, end)
35        return max(left_query, right_query)
36
37def longestRepeatingSubstring(s, queryCharacters, queryIndices):
38    st = SegmentTree(s)
39    lengths = []
40    for i in range(len(queryCharacters)):
41        st.update(queryIndices[i], queryCharacters[i], 0, 0, len(s) - 1)
42        lengths.append(st.query(0, len(s) - 1, 0, 0, len(s) - 1))
43    return lengths

Complexity note: The segment tree allows for efficient updates and queries, reducing the time complexity significantly compared to the brute force approach.

  • 1Understanding how to efficiently update and query data structures is crucial for performance.
  • 2Segment trees can significantly reduce the time complexity of problems involving dynamic updates.

Solutions and explanations are original Tejav content. Problem titles © LeetCode — use the LeetCode button above for the full problem statement.