Skip to content

Commit ce09488

Browse files
authored
Improved task 2213
1 parent dd1621e commit ce09488

File tree

1 file changed

+52
-70
lines changed
  • src/main/kotlin/g2201_2300/s2213_longest_substring_of_one_repeating_character

1 file changed

+52
-70
lines changed
Original file line numberDiff line numberDiff line change
@@ -1,89 +1,71 @@
11
package g2201_2300.s2213_longest_substring_of_one_repeating_character
22

33
// #Hard #Array #String #Ordered_Set #Segment_Tree
4-
// #2023_06_27_Time_879_ms_(100.00%)_Space_64.8_MB_(100.00%)
4+
// #2025_03_27_Time_73_ms_(100.00%)_Space_73.52_MB_(100.00%)
55

66
class Solution {
7-
internal class TreeNode(var start: Int, var end: Int) {
8-
var leftChar = 0.toChar()
9-
var leftCharLen = 0
10-
var rightChar = 0.toChar()
11-
var rightCharLen = 0
12-
var max = 0
13-
var left: TreeNode? = null
14-
var right: TreeNode? = null
15-
}
7+
private lateinit var ca: CharArray
168

179
fun longestRepeating(s: String, queryCharacters: String, queryIndices: IntArray): IntArray {
18-
val sChar = s.toCharArray()
19-
val qChar = queryCharacters.toCharArray()
20-
val root = buildTree(sChar, 0, sChar.size - 1)
21-
val result = IntArray(qChar.size)
22-
for (i in qChar.indices) {
23-
updateTree(root, queryIndices[i], qChar[i])
24-
if (root != null) {
25-
result[i] = root.max
26-
}
10+
ca = s.toCharArray()
11+
val result = IntArray(queryIndices.size)
12+
val root = SegmentTree(0, ca.size)
13+
for (i in queryIndices.indices) {
14+
ca[queryIndices[i]] = queryCharacters[i]
15+
root.update(queryIndices[i])
16+
result[i] = root.longest
2717
}
2818
return result
2919
}
3020

31-
private fun buildTree(s: CharArray, from: Int, to: Int): TreeNode? {
32-
if (from > to) {
33-
return null
34-
}
35-
val root = TreeNode(from, to)
36-
if (from == to) {
37-
root.max = 1
38-
root.leftChar = s[from]
39-
root.rightChar = root.leftChar
40-
root.rightCharLen = 1
41-
root.leftCharLen = root.rightCharLen
42-
return root
43-
}
44-
val middle = from + (to - from) / 2
45-
root.left = buildTree(s, from, middle)
46-
root.right = buildTree(s, middle + 1, to)
47-
updateNode(root)
48-
return root
49-
}
21+
private inner class SegmentTree(val start: Int, val end: Int) {
22+
var longest: Int = 0
23+
var leftLength: Int = 0
24+
var rightLength: Int = 0
25+
private lateinit var left: SegmentTree
26+
private lateinit var right: SegmentTree
5027

51-
private fun updateTree(root: TreeNode?, index: Int, c: Char) {
52-
if (root == null || root.start > index || root.end < index) {
53-
return
54-
}
55-
if (root.start == index && root.end == index) {
56-
root.rightChar = c
57-
root.leftChar = root.rightChar
58-
return
28+
init {
29+
if (end - start > 1) {
30+
val mid = (start + end) / 2
31+
left = SegmentTree(start, mid)
32+
right = SegmentTree(mid, end)
33+
merge()
34+
} else {
35+
longest = 1
36+
leftLength = 1
37+
rightLength = 1
38+
}
5939
}
60-
updateTree(root.left, index, c)
61-
updateTree(root.right, index, c)
62-
updateNode(root)
63-
}
6440

65-
private fun updateNode(root: TreeNode?) {
66-
if (root == null) {
67-
return
68-
}
69-
root.leftChar = root.left!!.leftChar
70-
root.leftCharLen = root.left!!.leftCharLen
71-
root.rightChar = root.right!!.rightChar
72-
root.rightCharLen = root.right!!.rightCharLen
73-
root.max = Math.max(root.left!!.max, root.right!!.max)
74-
if (root.left!!.rightChar == root.right!!.leftChar) {
75-
val len = root.left!!.rightCharLen + root.right!!.leftCharLen
76-
if (root.left!!.leftChar == root.left!!.rightChar &&
77-
root.left!!.leftCharLen == root.left!!.end - root.left!!.start + 1
78-
) {
79-
root.leftCharLen = len
41+
fun update(index: Int) {
42+
if (end - start == 1) return
43+
if (index < (left.end)) {
44+
left.update(index)
45+
} else {
46+
right.update(index)
8047
}
81-
if (root.right!!.leftChar == root.right!!.rightChar &&
82-
root.right!!.leftCharLen == root.right!!.end - root.right!!.start + 1
83-
) {
84-
root.rightCharLen = len
48+
merge()
49+
}
50+
51+
private fun merge() {
52+
longest = maxOf(left.longest, right.longest)
53+
if (ca[left.end - 1] == ca[right.start]) {
54+
longest = maxOf(longest, left.rightLength + right.leftLength)
55+
leftLength = if (left.leftLength == left.end - left.start) {
56+
left.leftLength + right.leftLength
57+
} else {
58+
left.leftLength
59+
}
60+
rightLength = if (right.rightLength == (right.end - right.start)) {
61+
right.rightLength + left.rightLength
62+
} else {
63+
right.rightLength
64+
}
65+
} else {
66+
leftLength = left.leftLength
67+
rightLength = right.rightLength
8568
}
86-
root.max = Math.max(root.max, len)
8769
}
8870
}
8971
}

0 commit comments

Comments
 (0)