Skip to content

Commit 1206f12

Browse files
committed
Add solution and test-cases for problem 3003
1 parent f03226b commit 1206f12

File tree

3 files changed

+116
-24
lines changed

3 files changed

+116
-24
lines changed

leetcode/3001-3100/3003.Maximize-the-Number-of-Partitions-After-Operations/README.md

Lines changed: 45 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,61 @@
11
# [3003.Maximize the Number of Partitions After Operations][title]
22

3-
> [!WARNING|style:flat]
4-
> This question is temporarily unanswered if you have good ideas. Welcome to [Create Pull Request PR](https://github.com/kylesliu/awesome-golang-algorithm)
5-
63
## Description
4+
You are given a string `s` and an integer `k`.
5+
6+
First, you are allowed to change **at most one** index in `s` to another lowercase English letter.
7+
8+
After that, do the following partitioning operation until `s` is **empty**:
9+
10+
- Choose the **longest prefix** of `s` containing at most `k` **distinct** characters.
11+
- **Delete** the prefix from `s` and increase the number of partitions by one. The remaining characters (if any) in `s` maintain their initial order.
12+
13+
Return an integer denoting the **maximum** number of resulting partitions after the operations by optimally choosing at most one index to change.
714

815
**Example 1:**
916

1017
```
11-
Input: a = "11", b = "1"
12-
Output: "100"
18+
Input: s = "accca", k = 2
19+
20+
Output: 3
21+
22+
Explanation:
23+
24+
The optimal way is to change s[2] to something other than a and c, for example, b. then it becomes "acbca".
25+
26+
Then we perform the operations:
27+
28+
The longest prefix containing at most 2 distinct characters is "ac", we remove it and s becomes "bca".
29+
Now The longest prefix containing at most 2 distinct characters is "bc", so we remove it and s becomes "a".
30+
Finally, we remove "a" and s becomes empty, so the procedure ends.
31+
Doing the operations, the string is divided into 3 partitions, so the answer is 3.
32+
```
33+
34+
**Example 2:**
35+
1336
```
37+
Input: s = "aabaab", k = 3
38+
39+
Output: 1
40+
41+
Explanation:
1442
15-
## 题意
16-
> ...
43+
Initially s contains 2 distinct characters, so whichever character we change, it will contain at most 3 distinct characters, so the longest prefix with at most 3 distinct characters would always be all of it, therefore the answer is 1.
44+
```
1745

18-
## 题解
46+
**Example 3:**
1947

20-
### 思路1
21-
> ...
22-
Maximize the Number of Partitions After Operations
23-
```go
2448
```
49+
Input: s = "xxyz", k = 1
50+
51+
Output: 4
52+
53+
Explanation:
2554
55+
The optimal way is to change s[0] or s[1] to something other than characters in s, for example, to change s[0] to w.
56+
57+
Then s becomes "wxyz", which consists of 4 distinct characters, so as k is 1, it will divide into 4 partitions.
58+
```
2659

2760
## 结语
2861

Lines changed: 60 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,63 @@
11
package Solution
22

3-
func Solution(x bool) bool {
4-
return x
3+
func Solution(s string, k int) int {
4+
n := len(s)
5+
left := make([][3]int, n)
6+
right := make([][3]int, n)
7+
8+
num, mask, count := 0, 0, 0
9+
for i := 0; i < n-1; i++ {
10+
binary := 1 << (s[i] - 'a')
11+
if mask&binary == 0 {
12+
count++
13+
if count <= k {
14+
mask |= binary
15+
} else {
16+
num++
17+
mask = binary
18+
count = 1
19+
}
20+
}
21+
left[i+1][0] = num
22+
left[i+1][1] = mask
23+
left[i+1][2] = count
24+
}
25+
26+
num, mask, count = 0, 0, 0
27+
for i := n - 1; i > 0; i-- {
28+
binary := 1 << (s[i] - 'a')
29+
if mask&binary == 0 {
30+
count++
31+
if count <= k {
32+
mask |= binary
33+
} else {
34+
num++
35+
mask = binary
36+
count = 1
37+
}
38+
}
39+
right[i-1][0] = num
40+
right[i-1][1] = mask
41+
right[i-1][2] = count
42+
}
43+
44+
maxVal := 0
45+
for i := 0; i < n; i++ {
46+
seg := left[i][0] + right[i][0] + 2
47+
totMask := left[i][1] | right[i][1]
48+
totCount := 0
49+
for totMask != 0 {
50+
totMask = totMask & (totMask - 1)
51+
totCount++
52+
}
53+
if left[i][2] == k && right[i][2] == k && totCount < 26 {
54+
seg++
55+
} else if min(totCount+1, 26) <= k {
56+
seg--
57+
}
58+
if seg > maxVal {
59+
maxVal = seg
60+
}
61+
}
62+
return maxVal
563
}

leetcode/3001-3100/3003.Maximize-the-Number-of-Partitions-After-Operations/Solution_test.go

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -10,30 +10,31 @@ func TestSolution(t *testing.T) {
1010
// 测试用例
1111
cases := []struct {
1212
name string
13-
inputs bool
14-
expect bool
13+
s string
14+
k int
15+
expect int
1516
}{
16-
{"TestCase", true, true},
17-
{"TestCase", true, true},
18-
{"TestCase", false, false},
17+
{"TestCase1", "accca", 2, 3},
18+
{"TestCase2", "aabaab", 3, 1},
19+
{"TestCase3", "xxyz", 1, 4},
1920
}
2021

2122
// 开始测试
2223
for i, c := range cases {
2324
t.Run(c.name+" "+strconv.Itoa(i), func(t *testing.T) {
24-
got := Solution(c.inputs)
25+
got := Solution(c.s, c.k)
2526
if !reflect.DeepEqual(got, c.expect) {
26-
t.Fatalf("expected: %v, but got: %v, with inputs: %v",
27-
c.expect, got, c.inputs)
27+
t.Fatalf("expected: %v, but got: %v, with inputs: %v %v",
28+
c.expect, got, c.s, c.k)
2829
}
2930
})
3031
}
3132
}
3233

33-
// 压力测试
34+
// 压力测试
3435
func BenchmarkSolution(b *testing.B) {
3536
}
3637

37-
// 使用案列
38+
// 使用案列
3839
func ExampleSolution() {
3940
}

0 commit comments

Comments
 (0)