Skip to content

Commit e5e9642

Browse files
committed
Improved task 3399
1 parent 22005bb commit e5e9642

File tree

2 files changed

+63
-66
lines changed
  • src
    • main/kotlin/g3301_3400/s3399_smallest_substring_with_identical_characters_ii
    • test/kotlin/g3301_3400/s3399_smallest_substring_with_identical_characters_ii

2 files changed

+63
-66
lines changed
Lines changed: 53 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -1,84 +1,71 @@
11
package g3301_3400.s3399_smallest_substring_with_identical_characters_ii
22

3-
// #Hard #2024_12_24_Time_22_ms_(100.00%)_Space_40.7_MB_(100.00%)
3+
// #Hard #2024_12_24_Time_26_ms_(100.00%)_Space_40.2_MB_(100.00%)
4+
5+
import kotlin.math.max
6+
import kotlin.math.min
47

58
class Solution {
69
fun minLength(s: String, numOps: Int): Int {
7-
val l = s.length
8-
var lingyi = 0
9-
var yiling = 0
10-
val pq: MutableList<Int> = ArrayList<Int>()
11-
var thisone = s[0]
12-
var chang = 1
13-
if (thisone == '0') {
14-
yiling++
15-
} else {
16-
lingyi++
17-
}
18-
for (i in 1..<l) {
19-
val cur = s[i]
20-
if (cur == thisone) {
21-
chang++
22-
} else {
23-
if (chang >= 2) {
24-
pq.add(chang)
25-
}
26-
chang = 1
27-
thisone = cur
10+
val b = s.toByteArray()
11+
var flips1 = 0
12+
var flips2 = 0
13+
for (i in b.indices) {
14+
val e1 = (if (i % 2 == 0) '0' else '1').code.toByte()
15+
val e2 = (if (i % 2 == 0) '1' else '0').code.toByte()
16+
if (b[i] != e1) {
17+
flips1++
2818
}
29-
if (i % 2 == 0) {
30-
if (cur == '0') {
31-
yiling++
32-
} else {
33-
lingyi++
34-
}
35-
} else {
36-
if (cur == '0') {
37-
lingyi++
38-
} else {
39-
yiling++
40-
}
19+
if (b[i] != e2) {
20+
flips2++
4121
}
4222
}
43-
if (numOps >= lingyi || numOps >= yiling) {
23+
val flips = min(flips1, flips2)
24+
if (flips <= numOps) {
4425
return 1
4526
}
46-
if (chang >= 2) {
47-
pq.add(chang)
48-
}
49-
var one = -1
50-
var two = -1
51-
for (cur in pq) {
52-
if (cur > one) {
53-
two = one
54-
one = cur
55-
} else if (cur > two) {
56-
two = cur
27+
val seg: MutableList<Int?> = ArrayList<Int?>()
28+
var count = 1
29+
var max = 1
30+
for (i in 1..<b.size) {
31+
if (b[i] != b[i - 1]) {
32+
if (count != 1) {
33+
seg.add(count)
34+
max = max(max, count)
35+
}
36+
count = 1
37+
} else {
38+
count++
5739
}
5840
}
59-
if (two == -1) {
60-
return if (one / (numOps + 1) > 1) one / (numOps + 1) else 2
61-
}
62-
if (numOps == 0) {
63-
return one
41+
if (count != 1) {
42+
seg.add(count)
43+
max = max(max, count)
6444
}
65-
if (numOps == 1) {
66-
return if (one / 2 > two) (if (one / 2 == 1) 2 else one / 2) else two
67-
}
68-
var left = 2
69-
var right = l / (numOps + 1)
70-
while (left < right) {
71-
val mid = left + (right - left) / 2
72-
var sum = 0
73-
for (integer in pq) {
74-
sum += integer / (mid + 1)
75-
}
76-
if (sum <= numOps) {
77-
right = mid
45+
var l = 2
46+
var r = max
47+
var res = max
48+
while (l <= r) {
49+
val m = l + (r - l) / 2
50+
if (check(m, seg, numOps)) {
51+
r = m - 1
52+
res = m
7853
} else {
79-
left = mid + 1
54+
l = m + 1
55+
}
56+
}
57+
return res
58+
}
59+
60+
private fun check(sz: Int, seg: MutableList<Int?>, ops: Int): Boolean {
61+
var ops = ops
62+
for (i in seg) {
63+
val x = i!! / (sz + 1)
64+
ops -= x
65+
if (ops < 0) {
66+
return false
8067
}
8168
}
82-
return left
69+
return true
8370
}
8471
}

src/test/kotlin/g3301_3400/s3399_smallest_substring_with_identical_characters_ii/SolutionTest.kt

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,4 +19,14 @@ internal class SolutionTest {
1919
fun minLength3() {
2020
assertThat<Int>(Solution().minLength("0101", 0), equalTo<Int>(1))
2121
}
22+
23+
@Test
24+
fun minLength4() {
25+
assertThat<Int>(Solution().minLength("000", 0), equalTo<Int>(3))
26+
}
27+
28+
@Test
29+
fun minLength5() {
30+
assertThat<Int>(Solution().minLength("000001", 1), equalTo<Int>(2))
31+
}
2232
}

0 commit comments

Comments
 (0)