diff --git a/leetcode/2101-2200/2182.Construct-String-With-Repeat-Limit/README.md b/leetcode/2101-2200/2182.Construct-String-With-Repeat-Limit/README.md index 41990ec30..2648c06e2 100755 --- a/leetcode/2101-2200/2182.Construct-String-With-Repeat-Limit/README.md +++ b/leetcode/2101-2200/2182.Construct-String-With-Repeat-Limit/README.md @@ -1,28 +1,38 @@ # [2182.Construct String With Repeat Limit][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 `repeatLimit`. Construct a new string `repeatLimitedString` using the characters of `s` such that no letter appears **more than** `repeatLimit` times **in a row**. You do **not** have to use all characters from `s`. + +Return the **lexicographically largest** `repeatLimitedString` possible. + +A string `a` is **lexicographically larger** than a string `b` if in the first position where `a` and `b` differ, string `a` has a letter that appears later in the alphabet than the corresponding letter in `b`. If the first `min(a.length, b.length)` characters do not differ, then the longer string is the lexicographically larger one. **Example 1:** ``` -Input: a = "11", b = "1" -Output: "100" +Input: s = "cczazcc", repeatLimit = 3 +Output: "zzcccac" +Explanation: We use all of the characters from s to construct the repeatLimitedString "zzcccac". +The letter 'a' appears at most 1 time in a row. +The letter 'c' appears at most 3 times in a row. +The letter 'z' appears at most 2 times in a row. +Hence, no letter appears more than repeatLimit times in a row and the string is a valid repeatLimitedString. +The string is the lexicographically largest repeatLimitedString possible so we return "zzcccac". +Note that the string "zzcccca" is lexicographically larger but the letter 'c' appears more than 3 times in a row, so it is not a valid repeatLimitedString. ``` -## 题意 -> ... +**Example 2:** -## 题解 - -### 思路1 -> ... -Construct String With Repeat Limit -```go ``` - +Input: s = "aababab", repeatLimit = 2 +Output: "bbabaa" +Explanation: We use only some of the characters from s to construct the repeatLimitedString "bbabaa". +The letter 'a' appears at most 2 times in a row. +The letter 'b' appears at most 2 times in a row. +Hence, no letter appears more than repeatLimit times in a row and the string is a valid repeatLimitedString. +The string is the lexicographically largest repeatLimitedString possible so we return "bbabaa". +Note that the string "bbabaaa" is lexicographically larger but the letter 'a' appears more than 2 times in a row, so it is not a valid repeatLimitedString. +``` ## 结语 diff --git a/leetcode/2101-2200/2182.Construct-String-With-Repeat-Limit/Solution.go b/leetcode/2101-2200/2182.Construct-String-With-Repeat-Limit/Solution.go index d115ccf5e..ff4064b50 100644 --- a/leetcode/2101-2200/2182.Construct-String-With-Repeat-Limit/Solution.go +++ b/leetcode/2101-2200/2182.Construct-String-With-Repeat-Limit/Solution.go @@ -1,5 +1,66 @@ package Solution -func Solution(x bool) bool { +import ( + "bytes" + "container/heap" +) + +type tmp2182 struct { + b byte + c int +} +type heap2182 []tmp2182 + +func (h *heap2182) Len() int { + return len(*h) +} + +func (h *heap2182) Less(i, j int) bool { + return (*h)[i].b > (*h)[j].b +} + +func (h *heap2182) Swap(i, j int) { + (*h)[i], (*h)[j] = (*h)[j], (*h)[i] +} + +func (h *heap2182) Push(x any) { + *h = append(*h, x.(tmp2182)) +} + +func (h *heap2182) Pop() any { + old := *h + l := len(old) + x := old[l-1] + *h = old[:l-1] return x } + +func Solution(s string, repeatLimit int) string { + c := make(map[byte]int) + for _, b := range []byte(s) { + c[b]++ + } + list := &heap2182{} + for k, v := range c { + heap.Push(list, tmp2182{k, v}) + } + buf := bytes.NewBuffer([]byte{}) + + for list.Len() > 0 { + top := heap.Pop(list).(tmp2182) + for range min(top.c, repeatLimit) { + buf.WriteByte(top.b) + } + top.c -= repeatLimit + if top.c > 0 && list.Len() > 0 { + nextPickOne := heap.Pop(list).(tmp2182) + buf.WriteByte(nextPickOne.b) + nextPickOne.c-- + if nextPickOne.c > 0 { + heap.Push(list, nextPickOne) + } + heap.Push(list, top) + } + } + return buf.String() +} diff --git a/leetcode/2101-2200/2182.Construct-String-With-Repeat-Limit/Solution_test.go b/leetcode/2101-2200/2182.Construct-String-With-Repeat-Limit/Solution_test.go index 14ff50eb4..061653c6e 100644 --- a/leetcode/2101-2200/2182.Construct-String-With-Repeat-Limit/Solution_test.go +++ b/leetcode/2101-2200/2182.Construct-String-With-Repeat-Limit/Solution_test.go @@ -10,30 +10,30 @@ func TestSolution(t *testing.T) { // 测试用例 cases := []struct { name string - inputs bool - expect bool + s string + limit int + expect string }{ - {"TestCase", true, true}, - {"TestCase", true, true}, - {"TestCase", false, false}, + {"TestCase1", "cczazcc", 3, "zzcccac"}, + {"TestCase2", "aababab", 2, "bbabaa"}, } // 开始测试 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.limit) 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.limit) } }) } } -// 压力测试 +// 压力测试 func BenchmarkSolution(b *testing.B) { } -// 使用案列 +// 使用案列 func ExampleSolution() { }