Skip to content

Commit f97a977

Browse files
authoredMar 25, 2025
Improved task 2213
1 parent cb89119 commit f97a977

File tree

1 file changed

+54
-74
lines changed
  • src/main/java/g2201_2300/s2213_longest_substring_of_one_repeating_character

1 file changed

+54
-74
lines changed
 
Original file line numberDiff line numberDiff line change
@@ -1,93 +1,73 @@
11
package g2201_2300.s2213_longest_substring_of_one_repeating_character;
22

33
// #Hard #Array #String #Ordered_Set #Segment_Tree
4-
// #2022_06_12_Time_141_ms_(86.81%)_Space_148.3_MB_(47.22%)
4+
// #2025_03_25_Time_79_ms_(89.74%)_Space_66.05_MB_(89.74%)
55

66
public class Solution {
7-
static class TreeNode {
8-
int start;
9-
int end;
10-
char leftChar;
11-
int leftCharLen;
12-
char rightChar;
13-
int rightCharLen;
14-
int max;
15-
TreeNode left;
16-
TreeNode right;
17-
18-
TreeNode(int start, int end) {
19-
this.start = start;
20-
this.end = end;
21-
left = null;
22-
right = null;
23-
}
24-
}
7+
private char[] ca;
258

269
public int[] longestRepeating(String s, String queryCharacters, int[] queryIndices) {
27-
char[] sChar = s.toCharArray();
28-
char[] qChar = queryCharacters.toCharArray();
29-
TreeNode root = buildTree(sChar, 0, sChar.length - 1);
30-
int[] result = new int[qChar.length];
31-
for (int i = 0; i < qChar.length; i++) {
32-
updateTree(root, queryIndices[i], qChar[i]);
33-
if (root != null) {
34-
result[i] = root.max;
35-
}
10+
ca = s.toCharArray();
11+
int[] result = new int[queryIndices.length];
12+
SegmentTree root = new SegmentTree(0, ca.length);
13+
for (int i = 0; i < queryIndices.length; i++) {
14+
ca[queryIndices[i]] = queryCharacters.charAt(i);
15+
root.update(queryIndices[i]);
16+
result[i] = root.longest;
3617
}
3718
return result;
3819
}
3920

40-
private TreeNode buildTree(char[] s, int from, int to) {
41-
if (from > to) {
42-
return null;
43-
}
44-
TreeNode root = new TreeNode(from, to);
45-
if (from == to) {
46-
root.max = 1;
47-
root.rightChar = root.leftChar = s[from];
48-
root.leftCharLen = root.rightCharLen = 1;
49-
return root;
50-
}
51-
int middle = from + (to - from) / 2;
52-
root.left = buildTree(s, from, middle);
53-
root.right = buildTree(s, middle + 1, to);
54-
updateNode(root);
55-
return root;
56-
}
21+
private class SegmentTree {
22+
final int start;
23+
final int end;
24+
int longest;
25+
int leftLength;
26+
int rightLength;
27+
SegmentTree left;
28+
SegmentTree right;
5729

58-
private void updateTree(TreeNode root, int index, char c) {
59-
if (root == null || root.start > index || root.end < index) {
60-
return;
61-
}
62-
if (root.start == index && root.end == index) {
63-
root.leftChar = root.rightChar = c;
64-
return;
30+
SegmentTree(int start, int end) {
31+
this.start = start;
32+
this.end = end;
33+
if (end - start > 1) {
34+
int mid = (start + end) / 2;
35+
left = new SegmentTree(start, mid);
36+
right = new SegmentTree(mid, end);
37+
merge();
38+
} else {
39+
longest = leftLength = rightLength = 1;
40+
}
6541
}
66-
updateTree(root.left, index, c);
67-
updateTree(root.right, index, c);
68-
updateNode(root);
69-
}
7042

71-
private void updateNode(TreeNode root) {
72-
if (root == null) {
73-
return;
74-
}
75-
root.leftChar = root.left.leftChar;
76-
root.leftCharLen = root.left.leftCharLen;
77-
root.rightChar = root.right.rightChar;
78-
root.rightCharLen = root.right.rightCharLen;
79-
root.max = Math.max(root.left.max, root.right.max);
80-
if (root.left.rightChar == root.right.leftChar) {
81-
int len = root.left.rightCharLen + root.right.leftCharLen;
82-
if (root.left.leftChar == root.left.rightChar
83-
&& root.left.leftCharLen == root.left.end - root.left.start + 1) {
84-
root.leftCharLen = len;
43+
void update(int index) {
44+
if (end - start == 1) {
45+
return;
46+
}
47+
if (index < left.end) {
48+
left.update(index);
49+
} else {
50+
right.update(index);
8551
}
86-
if (root.right.leftChar == root.right.rightChar
87-
&& root.right.leftCharLen == root.right.end - root.right.start + 1) {
88-
root.rightCharLen = len;
52+
merge();
53+
}
54+
55+
private void merge() {
56+
longest = Math.max(left.longest, right.longest);
57+
if (ca[left.end - 1] == ca[right.start]) {
58+
longest = Math.max(longest, left.rightLength + right.leftLength);
59+
leftLength =
60+
(left.leftLength == left.end - left.start)
61+
? left.leftLength + right.leftLength
62+
: left.leftLength;
63+
rightLength =
64+
(right.rightLength == right.end - right.start)
65+
? right.rightLength + left.rightLength
66+
: right.rightLength;
67+
} else {
68+
leftLength = left.leftLength;
69+
rightLength = right.rightLength;
8970
}
90-
root.max = Math.max(root.max, len);
9171
}
9272
}
9373
}

0 commit comments

Comments
 (0)