LeetCode 2213. Longest Substring of One Repeating Character Solution in Java, C++, Python & More | Explanation + Code

CoderIndeed
0
2213. Longest Substring of One Repeating Character

Description

You are given a 0-indexed string s. You are also given a 0-indexed string queryCharacters of length k and a 0-indexed array of integer indices queryIndices of length k, both of which are used to describe k queries.

The ith query updates the character in s at index queryIndices[i] to the character queryCharacters[i].

Return an array lengths of length k where lengths[i] is the length of the longest substring of s consisting of only one repeating character after the ith query is performed.

 

Example 1:

Input: s = "babacc", queryCharacters = "bcb", queryIndices = [1,3,3]
Output: [3,3,4]
Explanation: 
- 1st query updates s = "bbbacc". The longest substring consisting of one repeating character is "bbb" with length 3.
- 2nd query updates s = "bbbccc". 
  The longest substring consisting of one repeating character can be "bbb" or "ccc" with length 3.
- 3rd query updates s = "bbbbcc". The longest substring consisting of one repeating character is "bbbb" with length 4.
Thus, we return [3,3,4].

Example 2:

Input: s = "abyzz", queryCharacters = "aa", queryIndices = [2,1]
Output: [2,3]
Explanation:
- 1st query updates s = "abazz". The longest substring consisting of one repeating character is "zz" with length 2.
- 2nd query updates s = "aaazz". The longest substring consisting of one repeating character is "aaa" with length 3.
Thus, we return [2,3].

 

Constraints:

  • 1 <= s.length <= 105
  • s consists of lowercase English letters.
  • k == queryCharacters.length == queryIndices.length
  • 1 <= k <= 105
  • queryCharacters consists of lowercase English letters.
  • 0 <= queryIndices[i] < s.length

Solutions

Solution 1: Segment Tree

The segment tree divides the entire interval into multiple non-continuous sub-intervals, and the number of sub-intervals does not exceed log(width). To update the value of an element, you only need to update log(width) intervals, and these intervals are all contained in a large interval that contains the element. When modifying the interval, you need to use lazy tags to ensure efficiency.

  • Each node of the segment tree represents an interval;
  • The segment tree has a unique root node, which represents the entire statistical range, such as [1, n];
  • Each leaf node of the segment tree represents an elementary interval of length 1, [x, x];
  • For each internal node [l, r], its left child is [l, mid], and the right child is [mid + 1, r], where mid = l + r2;

For this problem, the information maintained by the segment tree node includes:

  1. The number of longest consecutive characters in the prefix, lmx;
  2. The number of longest consecutive characters in the suffix, rmx;
  3. The number of longest consecutive characters in the interval, mx.
  4. The left endpoint l and the right endpoint r of the interval.

The time complexity is O(n × log n), and the space complexity is O(n × log n). Where n is the length of the string s.

PythonJavaC++GoTypeScript
def max(a: int, b: int) -> int: return a if a > b else b class Node: __slots__ = "l", "r", "lmx", "rmx", "mx" def __init__(self, l: int, r: int): self.l = l self.r = r self.lmx = self.rmx = self.mx = 1 class SegmentTree: __slots__ = "s", "tr" def __init__(self, s: str): self.s = list(s) n = len(s) self.tr: List[Node | None] = [None] * (n * 4) self.build(1, 1, n) def build(self, u: int, l: int, r: int): self.tr[u] = Node(l, r) if l == r: return mid = (l + r) // 2 self.build(u << 1, l, mid) self.build(u << 1 | 1, mid + 1, r) self.pushup(u) def query(self, u: int, l: int, r: int) -> int: if self.tr[u].l >= l and self.tr[u].r <= r: return self.tr[u].mx mid = (self.tr[u].l + self.tr[u].r) // 2 ans = 0 if r <= mid: ans = self.query(u << 1, l, r) if l > mid: ans = max(ans, self.query(u << 1 | 1, l, r)) return ans def modify(self, u: int, x: int, v: str): if self.tr[u].l == self.tr[u].r: self.s[x - 1] = v return mid = (self.tr[u].l + self.tr[u].r) // 2 if x <= mid: self.modify(u << 1, x, v) else: self.modify(u << 1 | 1, x, v) self.pushup(u) def pushup(self, u: int): root, left, right = self.tr[u], self.tr[u << 1], self.tr[u << 1 | 1] root.lmx = left.lmx root.rmx = right.rmx root.mx = max(left.mx, right.mx) a, b = left.r - left.l + 1, right.r - right.l + 1 if self.s[left.r - 1] == self.s[right.l - 1]: if left.lmx == a: root.lmx += right.lmx if right.rmx == b: root.rmx += left.rmx root.mx = max(root.mx, left.rmx + right.lmx) class Solution: def longestRepeating( self, s: str, queryCharacters: str, queryIndices: List[int] ) -> List[int]: tree = SegmentTree(s) ans = [] for x, v in zip(queryIndices, queryCharacters): tree.modify(1, x + 1, v) ans.append(tree.query(1, 1, len(s))) return ans(code-box)

Post a Comment

0Comments

Post a Comment (0)

#buttons=(Accept !) #days=(20)

Our website uses cookies to enhance your experience. Check Now
Accept !