From 1206f12abc37593f4f1337b7c443c1e2ca8778bb Mon Sep 17 00:00:00 2001 From: 0xff-dev Date: Fri, 17 Oct 2025 08:57:46 +0800 Subject: [PATCH] Add solution and test-cases for problem 3003 --- .../README.md | 57 +++++++++++++---- .../Solution.go | 62 ++++++++++++++++++- .../Solution_test.go | 21 ++++--- 3 files changed, 116 insertions(+), 24 deletions(-) diff --git a/leetcode/3001-3100/3003.Maximize-the-Number-of-Partitions-After-Operations/README.md b/leetcode/3001-3100/3003.Maximize-the-Number-of-Partitions-After-Operations/README.md index 90b1ec018..f4ea2a80f 100755 --- a/leetcode/3001-3100/3003.Maximize-the-Number-of-Partitions-After-Operations/README.md +++ b/leetcode/3001-3100/3003.Maximize-the-Number-of-Partitions-After-Operations/README.md @@ -1,28 +1,61 @@ # [3003.Maximize the Number of Partitions After Operations][title] -> [!WARNING|style:flat] -> This question is temporarily unanswered if you have good ideas. Welcome to [Create Pull Request PR](https://github.com/kylesliu/awesome-golang-algorithm) - ## Description +You are given a string `s` and an integer `k`. + +First, you are allowed to change **at most one** index in `s` to another lowercase English letter. + +After that, do the following partitioning operation until `s` is **empty**: + +- Choose the **longest prefix** of `s` containing at most `k` **distinct** characters. +- **Delete** the prefix from `s` and increase the number of partitions by one. The remaining characters (if any) in `s` maintain their initial order. + +Return an integer denoting the **maximum** number of resulting partitions after the operations by optimally choosing at most one index to change. **Example 1:** ``` -Input: a = "11", b = "1" -Output: "100" +Input: s = "accca", k = 2 + +Output: 3 + +Explanation: + +The optimal way is to change s[2] to something other than a and c, for example, b. then it becomes "acbca". + +Then we perform the operations: + +The longest prefix containing at most 2 distinct characters is "ac", we remove it and s becomes "bca". +Now The longest prefix containing at most 2 distinct characters is "bc", so we remove it and s becomes "a". +Finally, we remove "a" and s becomes empty, so the procedure ends. +Doing the operations, the string is divided into 3 partitions, so the answer is 3. +``` + +**Example 2:** + ``` +Input: s = "aabaab", k = 3 + +Output: 1 + +Explanation: -## 题意 -> ... +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. +``` -## 题解 +**Example 3:** -### 思路1 -> ... -Maximize the Number of Partitions After Operations -```go ``` +Input: s = "xxyz", k = 1 + +Output: 4 + +Explanation: +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. + +Then s becomes "wxyz", which consists of 4 distinct characters, so as k is 1, it will divide into 4 partitions. +``` ## 结语 diff --git a/leetcode/3001-3100/3003.Maximize-the-Number-of-Partitions-After-Operations/Solution.go b/leetcode/3001-3100/3003.Maximize-the-Number-of-Partitions-After-Operations/Solution.go index d115ccf5e..7daa290c7 100644 --- a/leetcode/3001-3100/3003.Maximize-the-Number-of-Partitions-After-Operations/Solution.go +++ b/leetcode/3001-3100/3003.Maximize-the-Number-of-Partitions-After-Operations/Solution.go @@ -1,5 +1,63 @@ package Solution -func Solution(x bool) bool { - return x +func Solution(s string, k int) int { + n := len(s) + left := make([][3]int, n) + right := make([][3]int, n) + + num, mask, count := 0, 0, 0 + for i := 0; i < n-1; i++ { + binary := 1 << (s[i] - 'a') + if mask&binary == 0 { + count++ + if count <= k { + mask |= binary + } else { + num++ + mask = binary + count = 1 + } + } + left[i+1][0] = num + left[i+1][1] = mask + left[i+1][2] = count + } + + num, mask, count = 0, 0, 0 + for i := n - 1; i > 0; i-- { + binary := 1 << (s[i] - 'a') + if mask&binary == 0 { + count++ + if count <= k { + mask |= binary + } else { + num++ + mask = binary + count = 1 + } + } + right[i-1][0] = num + right[i-1][1] = mask + right[i-1][2] = count + } + + maxVal := 0 + for i := 0; i < n; i++ { + seg := left[i][0] + right[i][0] + 2 + totMask := left[i][1] | right[i][1] + totCount := 0 + for totMask != 0 { + totMask = totMask & (totMask - 1) + totCount++ + } + if left[i][2] == k && right[i][2] == k && totCount < 26 { + seg++ + } else if min(totCount+1, 26) <= k { + seg-- + } + if seg > maxVal { + maxVal = seg + } + } + return maxVal } diff --git a/leetcode/3001-3100/3003.Maximize-the-Number-of-Partitions-After-Operations/Solution_test.go b/leetcode/3001-3100/3003.Maximize-the-Number-of-Partitions-After-Operations/Solution_test.go index 14ff50eb4..b31b2a27b 100644 --- a/leetcode/3001-3100/3003.Maximize-the-Number-of-Partitions-After-Operations/Solution_test.go +++ b/leetcode/3001-3100/3003.Maximize-the-Number-of-Partitions-After-Operations/Solution_test.go @@ -10,30 +10,31 @@ func TestSolution(t *testing.T) { // 测试用例 cases := []struct { name string - inputs bool - expect bool + s string + k int + expect int }{ - {"TestCase", true, true}, - {"TestCase", true, true}, - {"TestCase", false, false}, + {"TestCase1", "accca", 2, 3}, + {"TestCase2", "aabaab", 3, 1}, + {"TestCase3", "xxyz", 1, 4}, } // 开始测试 for i, c := range cases { t.Run(c.name+" "+strconv.Itoa(i), func(t *testing.T) { - got := Solution(c.inputs) + got := Solution(c.s, c.k) if !reflect.DeepEqual(got, c.expect) { - t.Fatalf("expected: %v, but got: %v, with inputs: %v", - c.expect, got, c.inputs) + t.Fatalf("expected: %v, but got: %v, with inputs: %v %v", + c.expect, got, c.s, c.k) } }) } } -// 压力测试 +// 压力测试 func BenchmarkSolution(b *testing.B) { } -// 使用案列 +// 使用案列 func ExampleSolution() { }