diff --git a/leetcode/5617.Goal-Parser-Interpretation/5617. Goal Parser Interpretation.go b/leetcode/1678.Goal-Parser-Interpretation/1678. Goal Parser Interpretation.go similarity index 96% rename from leetcode/5617.Goal-Parser-Interpretation/5617. Goal Parser Interpretation.go rename to leetcode/1678.Goal-Parser-Interpretation/1678. Goal Parser Interpretation.go index d450417b..de161200 100644 --- a/leetcode/5617.Goal-Parser-Interpretation/5617. Goal Parser Interpretation.go +++ b/leetcode/1678.Goal-Parser-Interpretation/1678. Goal Parser Interpretation.go @@ -14,7 +14,7 @@ func interpret(command string) string { i += 3 } else { res += "o" - i += 1 + i++ } } } diff --git a/leetcode/1678.Goal-Parser-Interpretation/1678. Goal Parser Interpretation_test.go b/leetcode/1678.Goal-Parser-Interpretation/1678. Goal Parser Interpretation_test.go new file mode 100644 index 00000000..588368aa --- /dev/null +++ b/leetcode/1678.Goal-Parser-Interpretation/1678. Goal Parser Interpretation_test.go @@ -0,0 +1,52 @@ +package leetcode + +import ( + "fmt" + "testing" +) + +type question1678 struct { + para1678 + ans1678 +} + +// para 是参数 +// one 代表第一个参数 +type para1678 struct { + command string +} + +// ans 是答案 +// one 代表第一个答案 +type ans1678 struct { + one string +} + +func Test_Problem1678(t *testing.T) { + + qs := []question1678{ + + { + para1678{"G()(al)"}, + ans1678{"Goal"}, + }, + + { + para1678{"G()()()()(al)"}, + ans1678{"Gooooal"}, + }, + + { + para1678{"(al)G(al)()()G"}, + ans1678{"alGalooG"}, + }, + } + + fmt.Printf("------------------------Leetcode Problem 1678------------------------\n") + + for _, q := range qs { + _, p := q.ans1678, q.para1678 + fmt.Printf("【input】:%v 【output】:%v\n", p, interpret(p.command)) + } + fmt.Printf("\n\n\n") +} diff --git a/leetcode/1678.Goal-Parser-Interpretation/README.md b/leetcode/1678.Goal-Parser-Interpretation/README.md new file mode 100644 index 00000000..4f8145f4 --- /dev/null +++ b/leetcode/1678.Goal-Parser-Interpretation/README.md @@ -0,0 +1,73 @@ +# [1678. Goal Parser Interpretation](https://leetcode.com/problems/goal-parser-interpretation/) + +## 题目 + +You own a **Goal Parser** that can interpret a string `command`. The `command` consists of an alphabet of `"G"`, `"()"` and/or `"(al)"` in some order. The Goal Parser will interpret `"G"` as the string `"G"`, `"()"` as the string `"o"`, and `"(al)"` as the string `"al"`. The interpreted strings are then concatenated in the original order. + +Given the string `command`, return *the **Goal Parser**'s interpretation of* `command`. + +**Example 1:** + +``` +Input: command = "G()(al)" +Output: "Goal" +Explanation: The Goal Parser interprets the command as follows: +G -> G +() -> o +(al) -> al +The final concatenated result is "Goal". +``` + +**Example 2:** + +``` +Input: command = "G()()()()(al)" +Output: "Gooooal" +``` + +**Example 3:** + +``` +Input: command = "(al)G(al)()()G" +Output: "alGalooG" +``` + +**Constraints:** + +- `1 <= command.length <= 100` +- `command` consists of `"G"`, `"()"`, and/or `"(al)"` in some order. + +## 题目大意 + +请你设计一个可以解释字符串 command 的 Goal 解析器 。command 由 "G"、"()" 和/或 "(al)" 按某种顺序组成。Goal 解析器会将 "G" 解释为字符串 "G"、"()" 解释为字符串 "o" ,"(al)" 解释为字符串 "al" 。然后,按原顺序将经解释得到的字符串连接成一个字符串。给你字符串 command ,返回 Goal 解析器 对 command 的解释结果。 + +## 解题思路 + +- 简单题,按照题意修改字符串即可。由于是简单题,这一题也不用考虑嵌套的情况。 + +## 代码 + +```go +package leetcode + +func interpret(command string) string { + if command == "" { + return "" + } + res := "" + for i := 0; i < len(command); i++ { + if command[i] == 'G' { + res += "G" + } else { + if command[i] == '(' && command[i+1] == 'a' { + res += "al" + i += 3 + } else { + res += "o" + i ++ + } + } + } + return res +} +``` \ No newline at end of file diff --git a/leetcode/1679.Max-Number-of-K-Sum-Pairs/1679. Max Number of K-Sum Pairs.go b/leetcode/1679.Max-Number-of-K-Sum-Pairs/1679. Max Number of K-Sum Pairs.go new file mode 100644 index 00000000..8a601ffa --- /dev/null +++ b/leetcode/1679.Max-Number-of-K-Sum-Pairs/1679. Max Number of K-Sum Pairs.go @@ -0,0 +1,48 @@ +package leetcode + +// 解法一 优化版 +func maxOperations(nums []int, k int) int { + counter, res := make(map[int]int), 0 + for _, n := range nums { + counter[n]++ + } + if (k & 1) == 0 { + res += counter[k>>1] >> 1 + // 能够由 2 个相同的数构成 k 的组合已经都排除出去了,剩下的一个单独的也不能组成 k 了 + // 所以这里要把它的频次置为 0 。如果这里不置为 0,下面代码判断逻辑还需要考虑重复使用数字的情况 + counter[k>>1] = 0 + } + for num, freq := range counter { + if num <= k/2 { + remain := k - num + if counter[remain] < freq { + res += counter[remain] + } else { + res += freq + } + } + } + return res +} + +// 解法二 +func maxOperations_(nums []int, k int) int { + counter, res := make(map[int]int), 0 + for _, num := range nums { + counter[num]++ + remain := k - num + if num == remain { + if counter[num] >= 2 { + res++ + counter[num] -= 2 + } + } else { + if counter[remain] > 0 { + res++ + counter[remain]-- + counter[num]-- + } + } + } + return res +} diff --git a/leetcode/1679.Max-Number-of-K-Sum-Pairs/1679. Max Number of K-Sum Pairs_test.go b/leetcode/1679.Max-Number-of-K-Sum-Pairs/1679. Max Number of K-Sum Pairs_test.go new file mode 100644 index 00000000..c9a96b2b --- /dev/null +++ b/leetcode/1679.Max-Number-of-K-Sum-Pairs/1679. Max Number of K-Sum Pairs_test.go @@ -0,0 +1,58 @@ +package leetcode + +import ( + "fmt" + "testing" +) + +type question1679 struct { + para1679 + ans1679 +} + +// para 是参数 +// one 代表第一个参数 +type para1679 struct { + nums []int + k int +} + +// ans 是答案 +// one 代表第一个答案 +type ans1679 struct { + one int +} + +func Test_Problem1679(t *testing.T) { + + qs := []question1679{ + + { + para1679{[]int{1, 2, 3, 4}, 5}, + ans1679{2}, + }, + + { + para1679{[]int{3, 1, 3, 4, 3}, 6}, + ans1679{1}, + }, + + { + para1679{[]int{2, 5, 4, 4, 1, 3, 4, 4, 1, 4, 4, 1, 2, 1, 2, 2, 3, 2, 4, 2}, 3}, + ans1679{4}, + }, + + { + para1679{[]int{2, 5, 5, 5, 1, 3, 4, 4, 1, 4, 4, 1, 3, 1, 3, 1, 3, 2, 4, 2}, 6}, + ans1679{8}, + }, + } + + fmt.Printf("------------------------Leetcode Problem 1679------------------------\n") + + for _, q := range qs { + _, p := q.ans1679, q.para1679 + fmt.Printf("【input】:%v 【output】:%v\n", p, maxOperations(p.nums, p.k)) + } + fmt.Printf("\n\n\n") +} diff --git a/leetcode/1679.Max-Number-of-K-Sum-Pairs/README.md b/leetcode/1679.Max-Number-of-K-Sum-Pairs/README.md new file mode 100644 index 00000000..83ed4b31 --- /dev/null +++ b/leetcode/1679.Max-Number-of-K-Sum-Pairs/README.md @@ -0,0 +1,98 @@ +# [1679. Max Number of K-Sum Pairs](https://leetcode.com/problems/max-number-of-k-sum-pairs/) + + +## 题目 + +You are given an integer array `nums` and an integer `k`. + +In one operation, you can pick two numbers from the array whose sum equals `k` and remove them from the array. + +Return *the maximum number of operations you can perform on the array*. + +**Example 1:** + +``` +Input: nums = [1,2,3,4], k = 5 +Output: 2 +Explanation: Starting with nums = [1,2,3,4]: +- Remove numbers 1 and 4, then nums = [2,3] +- Remove numbers 2 and 3, then nums = [] +There are no more pairs that sum up to 5, hence a total of 2 operations. +``` + +**Example 2:** + +``` +Input: nums = [3,1,3,4,3], k = 6 +Output: 1 +Explanation: Starting with nums = [3,1,3,4,3]: +- Remove the first two 3's, then nums = [1,4,3] +There are no more pairs that sum up to 6, hence a total of 1 operation. +``` + +**Constraints:** + +- `1 <= nums.length <= 105` +- `1 <= nums[i] <= 109` +- `1 <= k <= 109` + +## 题目大意 + +给你一个整数数组 nums 和一个整数 k 。每一步操作中,你需要从数组中选出和为 k 的两个整数,并将它们移出数组。返回你可以对数组执行的最大操作数。 + +## 解题思路 + +- 读完题第一感觉这道题是 TWO SUM 题目的加强版。需要找到所有满足和是 k 的数对。先考虑能不能找到两个数都是 k/2 ,如果能找到多个这样的数,可以先移除他们。其次在利用 TWO SUM 的思路,找出和为 k 的数对。利用 TWO SUM 里面 map 的做法,时间复杂度 O(n)。 + +## 代码 + +```go +package leetcode + +// 解法一 优化版 +func maxOperations(nums []int, k int) int { + counter, res := make(map[int]int), 0 + for _, n := range nums { + counter[n]++ + } + if (k & 1) == 0 { + res += counter[k>>1] >> 1 + // 能够由 2 个相同的数构成 k 的组合已经都排除出去了,剩下的一个单独的也不能组成 k 了 + // 所以这里要把它的频次置为 0 。如果这里不置为 0,下面代码判断逻辑还需要考虑重复使用数字的情况 + counter[k>>1] = 0 + } + for num, freq := range counter { + if num <= k/2 { + remain := k - num + if counter[remain] < freq { + res += counter[remain] + } else { + res += freq + } + } + } + return res +} + +// 解法二 +func maxOperations_(nums []int, k int) int { + counter, res := make(map[int]int), 0 + for _, num := range nums { + counter[num]++ + remain := k - num + if num == remain { + if counter[num] >= 2 { + res++ + counter[num] -= 2 + } + } else { + if counter[remain] > 0 { + res++ + counter[remain]-- + counter[num]-- + } + } + } + return res +} +``` \ No newline at end of file diff --git a/leetcode/1680.Concatenation-of-Consecutive-Binary-Numbers/1680. Concatenation of Consecutive Binary Numbers.go b/leetcode/1680.Concatenation-of-Consecutive-Binary-Numbers/1680. Concatenation of Consecutive Binary Numbers.go new file mode 100644 index 00000000..eff4e12b --- /dev/null +++ b/leetcode/1680.Concatenation-of-Consecutive-Binary-Numbers/1680. Concatenation of Consecutive Binary Numbers.go @@ -0,0 +1,26 @@ +package leetcode + +import ( + "math/bits" +) + +// 解法一 模拟 +func concatenatedBinary(n int) int { + res, mod, shift := 0, 1000000007, 0 + for i := 1; i <= n; i++ { + if (i & (i - 1)) == 0 { + shift++ + } + res = ((res << shift) + i) % mod + } + return res +} + +// 解法二 位运算 +func concatenatedBinary1(n int) int { + res := 0 + for i := 1; i <= n; i++ { + res = (res< k { + return -1 + } + } + orders := []int{} + for i := range counts { + orders = append(orders, i) + } + sort.Ints(orders) + res := math.MaxInt32 + generatePermutation1681(nums, counts, orders, 0, 0, eachSize, &res, []int{}) + if res == math.MaxInt32 { + return -1 + } + return res +} + +func generatePermutation1681(nums, counts, order []int, index, sum, eachSize int, res *int, current []int) { + if len(current) > 0 && len(current)%eachSize == 0 { + sum += current[len(current)-1] - current[len(current)-eachSize] + index = 0 + } + if sum >= *res { + return + } + if len(current) == len(nums) { + if sum < *res { + *res = sum + } + return + } + for i := index; i < len(counts); i++ { + if counts[order[i]] == 0 { + continue + } + counts[order[i]]-- + current = append(current, order[i]) + generatePermutation1681(nums, counts, order, i+1, sum, eachSize, res, current) + current = current[:len(current)-1] + counts[order[i]]++ + // 这里是关键的剪枝 + if index == 0 { + break + } + } +} diff --git a/leetcode/1681.Minimum-Incompatibility/1681. Minimum Incompatibility_test.go b/leetcode/1681.Minimum-Incompatibility/1681. Minimum Incompatibility_test.go new file mode 100644 index 00000000..903c963b --- /dev/null +++ b/leetcode/1681.Minimum-Incompatibility/1681. Minimum Incompatibility_test.go @@ -0,0 +1,53 @@ +package leetcode + +import ( + "fmt" + "testing" +) + +type question1681 struct { + para1681 + ans1681 +} + +// para 是参数 +// one 代表第一个参数 +type para1681 struct { + nums []int + k int +} + +// ans 是答案 +// one 代表第一个答案 +type ans1681 struct { + one int +} + +func Test_Problem1681(t *testing.T) { + + qs := []question1681{ + + { + para1681{[]int{1, 2, 1, 4}, 2}, + ans1681{4}, + }, + + { + para1681{[]int{6, 3, 8, 1, 3, 1, 2, 2}, 4}, + ans1681{6}, + }, + + { + para1681{[]int{5, 3, 3, 6, 3, 3}, 3}, + ans1681{-1}, + }, + } + + fmt.Printf("------------------------Leetcode Problem 1681------------------------\n") + + for _, q := range qs { + _, p := q.ans1681, q.para1681 + fmt.Printf("【input】:%v 【output】:%v\n", p, minimumIncompatibility(p.nums, p.k)) + } + fmt.Printf("\n\n\n") +} diff --git a/leetcode/1681.Minimum-Incompatibility/README.md b/leetcode/1681.Minimum-Incompatibility/README.md new file mode 100644 index 00000000..a46fd91e --- /dev/null +++ b/leetcode/1681.Minimum-Incompatibility/README.md @@ -0,0 +1,122 @@ +# [1681. Minimum Incompatibility](https://leetcode.com/problems/minimum-incompatibility/) + + +## 题目 + +You are given an integer array `nums` and an integer `k`. You are asked to distribute this array into `k` subsets of **equal size** such that there are no two equal elements in the same subset. + +A subset's **incompatibility** is the difference between the maximum and minimum elements in that array. + +Return *the **minimum possible sum of incompatibilities** of the* `k` *subsets after distributing the array optimally, or return* `-1` *if it is not possible.* + +A subset is a group integers that appear in the array with no particular order. + +**Example 1:** + +``` +Input: nums = [1,2,1,4], k = 2 +Output: 4 +Explanation: The optimal distribution of subsets is [1,2] and [1,4]. +The incompatibility is (2-1) + (4-1) = 4. +Note that [1,1] and [2,4] would result in a smaller sum, but the first subset contains 2 equal elements. +``` + +**Example 2:** + +``` +Input: nums = [6,3,8,1,3,1,2,2], k = 4 +Output: 6 +Explanation: The optimal distribution of subsets is [1,2], [2,3], [6,8], and [1,3]. +The incompatibility is (2-1) + (3-2) + (8-6) + (3-1) = 6. + +``` + +**Example 3:** + +``` +Input: nums = [5,3,3,6,3,3], k = 3 +Output: -1 +Explanation: It is impossible to distribute nums into 3 subsets where no two elements are equal in the same subset. + +``` + +**Constraints:** + +- `1 <= k <= nums.length <= 16` +- `nums.length` is divisible by `k` +- `1 <= nums[i] <= nums.length` + +## 题目大意 + +给你一个整数数组 nums 和一个整数 k 。你需要将这个数组划分到 k 个相同大小的子集中,使得同一个子集里面没有两个相同的元素。一个子集的 不兼容性 是该子集里面最大值和最小值的差。 + +请你返回将数组分成 k 个子集后,各子集 **不兼容性** 的 **和** 的 **最小值** ,如果无法分成分成 k 个子集,返回 -1 。子集的定义是数组中一些数字的集合,对数字顺序没有要求。 + +## 解题思路 + +- 读完题最直白的思路就是 DFS。做法类似第 77 题。这里就不赘述了。可以见第 77 题题解。 +- 这一题还需要用到贪心的思想。每次取数都取最小的数。这样可以不会让最大数和最小数在一个集合中。由于每次取数都是取最小的,那么能保证不兼容性每次都尽量最小。于是在 order 数组中定义取数的顺序。然后再把数组从小到大排列。这样每次按照 order 顺序取数,都是取的最小值。 +- 正常的 DFS 写完提交,耗时是很长的。大概是 1532ms。如何优化到极致呢?这里需要加上 2 个剪枝条件。第一个剪枝条件比较简单,如果累计 sum 比之前存储的 res 大,那么直接 return,不需要继续递归了。第二个剪枝条件就非常重要了,可以一下子减少很多次递归。每次取数产生新的集合的时候,要从第一个最小数开始取,一旦取了,后面就不需要再循环递归了。举个例子,[1,2,3,4],第一个数如果取 2,集合可以是 [[2,3],[1,4]] 或 [[2,4], [1,3]], 这个集合和[[1,3],[2,4]]、[[1,4], [2,3]] 情况一样。可以看到如果取出第一个最小值以后,后面的循环是不必要的了。所以在取下标为 0 的数的时候,递归到底层以后,返回就可以直接 break,不用接下去的循环了,接下去的循环和递归是不必要的。加了这 2 个剪枝条件以后,耗时就变成了 0ms 了。beats 100% + +## 代码 + +```go +package leetcode + +import ( + "math" + "sort" +) + +func minimumIncompatibility(nums []int, k int) int { + sort.Ints(nums) + eachSize, counts := len(nums)/k, make([]int, len(nums)+1) + for i := range nums { + counts[nums[i]]++ + if counts[nums[i]] > k { + return -1 + } + } + orders := []int{} + for i := range counts { + orders = append(orders, i) + } + sort.Ints(orders) + res := math.MaxInt32 + generatePermutation1681(nums, counts, orders, 0, 0, eachSize, &res, []int{}) + if res == math.MaxInt32 { + return -1 + } + return res +} + +func generatePermutation1681(nums, counts, order []int, index, sum, eachSize int, res *int, current []int) { + if len(current) > 0 && len(current)%eachSize == 0 { + sum += current[len(current)-1] - current[len(current)-eachSize] + index = 0 + } + if sum >= *res { + return + } + if len(current) == len(nums) { + if sum < *res { + *res = sum + } + return + } + for i := index; i < len(counts); i++ { + if counts[order[i]] == 0 { + continue + } + counts[order[i]]-- + current = append(current, order[i]) + generatePermutation1681(nums, counts, order, i+1, sum, eachSize, res, current) + current = current[:len(current)-1] + counts[order[i]]++ + // 这里是关键的剪枝 + if index == 0 { + break + } + } +} +``` \ No newline at end of file diff --git a/leetcode/5617.Goal-Parser-Interpretation/5617. Goal Parser Interpretation_test.go b/leetcode/5617.Goal-Parser-Interpretation/5617. Goal Parser Interpretation_test.go deleted file mode 100644 index 9d70531c..00000000 --- a/leetcode/5617.Goal-Parser-Interpretation/5617. Goal Parser Interpretation_test.go +++ /dev/null @@ -1,63 +0,0 @@ -package leetcode - -import ( - "fmt" - "testing" -) - -type question491 struct { - para491 - ans491 -} - -// para 是参数 -// one 代表第一个参数 -type para491 struct { - nums []int - k int -} - -// ans 是答案 -// one 代表第一个答案 -type ans491 struct { - one []int -} - -func Test_Problem491(t *testing.T) { - - qs := []question491{ - - { - para491{[]int{3, 5, 2, 6}, 2}, - ans491{[]int{2, 6}}, - }, - - { - para491{[]int{2, 4, 3, 3, 5, 4, 9, 6}, 4}, - ans491{[]int{2, 3, 3, 4}}, - }, - - { - para491{[]int{2, 4, 3, 3, 5, 4, 9, 6}, 4}, - ans491{[]int{2, 3, 3, 4}}, - }, - - { - para491{[]int{71, 18, 52, 29, 55, 73, 24, 42, 66, 8, 80, 2}, 3}, - ans491{[]int{8, 80, 2}}, - }, - - { - para491{[]int{84, 10, 71, 23, 66, 61, 62, 64, 34, 41, 80, 25, 91, 43, 4, 75, 65, 13, 37, 41, 46, 90, 55, 8, 85, 61, 95, 71}, 24}, - ans491{[]int{10, 23, 61, 62, 34, 41, 80, 25, 91, 43, 4, 75, 65, 13, 37, 41, 46, 90, 55, 8, 85, 61, 95, 71}}, - }, - } - - fmt.Printf("------------------------Leetcode Problem 491------------------------\n") - - for _, q := range qs { - _, p := q.ans491, q.para491 - fmt.Printf("【input】:%v 【output】:%v\n", p, mostCompetitive(p.nums, p.k)) - } - fmt.Printf("\n\n\n") -} diff --git a/leetcode/5618.Max-Number-of-K-Sum-Pairs/5618. Max Number of K-Sum Pairs.go b/leetcode/5618.Max-Number-of-K-Sum-Pairs/5618. Max Number of K-Sum Pairs.go deleted file mode 100644 index c87c8e7c..00000000 --- a/leetcode/5618.Max-Number-of-K-Sum-Pairs/5618. Max Number of K-Sum Pairs.go +++ /dev/null @@ -1,56 +0,0 @@ -package leetcode - -import ( - "fmt" - "sort" -) - -func maxOperations(nums []int, k int) int { - if len(nums) == 0 { - return 0 - } - c, res, ans, used := []int{}, [][]int{}, 0, make([]bool, len(nums)) - sort.Ints(nums) - findcombinationSum(nums, k, 0, c, &res, &used) - fmt.Printf("res = %v\n", res) - for i := 0; i < len(res); i++ { - ans = max(ans, len(res[i])) - } - return ans -} - -func findcombinationSum(nums []int, k, index int, c []int, res *[][]int, used *[]bool) { - if k <= 0 { - if k == 0 && len(c) == 2 { - fmt.Printf("used = %v nums = %v\n", used, nums) - b := make([]int, len(c)) - copy(b, c) - *res = append(*res, b) - } - return - } - - for i := index; i < len(nums); i++ { - if !(*used)[i] { - if nums[i] > k { // 这里可以剪枝优化 - break - } - // if i > 0 && nums[i] == nums[i-1] && !(*used)[i-1] { // 这里是去重的关键逻辑 - // continue - // } - (*used)[i] = true - c = append(c, nums[i]) - findcombinationSum(nums, k-nums[i], i+1, c, res, used) // 注意这里迭代的时候 index 依旧不变,因为一个元素可以取多次 - c = c[:len(c)-1] - (*used)[i] = false - } - } -} - -func max(a, b int) int { - if a > b { - return a - } else { - return b - } -} diff --git a/leetcode/5618.Max-Number-of-K-Sum-Pairs/5618. Max Number of K-Sum Pairs_test.go b/leetcode/5618.Max-Number-of-K-Sum-Pairs/5618. Max Number of K-Sum Pairs_test.go deleted file mode 100644 index 4980bee4..00000000 --- a/leetcode/5618.Max-Number-of-K-Sum-Pairs/5618. Max Number of K-Sum Pairs_test.go +++ /dev/null @@ -1,53 +0,0 @@ -package leetcode - -import ( - "fmt" - "testing" -) - -type question5618 struct { - para5618 - ans5618 -} - -// para 是参数 -// one 代表第一个参数 -type para5618 struct { - nums []int - k int -} - -// ans 是答案 -// one 代表第一个答案 -type ans5618 struct { - one int -} - -func Test_Problem5618(t *testing.T) { - - qs := []question5618{ - - { - para5618{[]int{1, 2, 3, 4}, 5}, - ans5618{2}, - }, - - { - para5618{[]int{3, 1, 3, 4, 3}, 6}, - ans5618{1}, - }, - - { - para5618{[]int{2, 5, 4, 4, 1, 3, 4, 4, 1, 4, 4, 1, 2, 1, 2, 2, 3, 2, 4, 2}, 3}, - ans5618{4}, - }, - } - - fmt.Printf("------------------------Leetcode Problem 5618------------------------\n") - - for _, q := range qs { - _, p := q.ans5618, q.para5618 - fmt.Printf("【input】:%v 【output】:%v\n", p, maxOperations(p.nums, p.k)) - } - fmt.Printf("\n\n\n") -} diff --git a/leetcode/5620.Concatenation-of-Consecutive-Binary-Numbers/5620. Concatenation of Consecutive Binary Numbers.go b/leetcode/5620.Concatenation-of-Consecutive-Binary-Numbers/5620. Concatenation of Consecutive Binary Numbers.go deleted file mode 100644 index c638c9be..00000000 --- a/leetcode/5620.Concatenation-of-Consecutive-Binary-Numbers/5620. Concatenation of Consecutive Binary Numbers.go +++ /dev/null @@ -1,49 +0,0 @@ -package leetcode - -import ( - "fmt" - "math/big" - "strconv" -) - -func concatenatedBinary(n int) int { - if n == 42 { - return 727837408 - } - str := "" - for i := 1; i <= n; i++ { - str += convertToBin(i) - } - fmt.Printf("str = %v\n", str) - bigInt := Str2DEC(str) - bigInt.Mod(bigInt, big.NewInt(1000000007)) - return int(bigInt.Int64()) -} - -func convertToBin(num int) string { - s := "" - if num == 0 { - return "0" - } - // num /= 2 每次循环的时候 都将num除以2 再把结果赋值给 num - for ; num > 0; num /= 2 { - lsb := num % 2 - // strconv.Itoa() 将数字强制性转化为字符串 - s = strconv.Itoa(lsb) + s - } - return s -} - -func Str2DEC(s string) *big.Int { - l := len(s) - // num := big.NewInt(0) - z := new(big.Int) - fmt.Printf("num = %v\n", z) - for i := l - 1; i >= 0; i-- { - z.Add(big.NewInt(int64((int(s[l-i-1])&0xf)< G +() -> o +(al) -> al +The final concatenated result is "Goal". +``` + +**Example 2:** + +``` +Input: command = "G()()()()(al)" +Output: "Gooooal" +``` + +**Example 3:** + +``` +Input: command = "(al)G(al)()()G" +Output: "alGalooG" +``` + +**Constraints:** + +- `1 <= command.length <= 100` +- `command` consists of `"G"`, `"()"`, and/or `"(al)"` in some order. + +## 题目大意 + +请你设计一个可以解释字符串 command 的 Goal 解析器 。command 由 "G"、"()" 和/或 "(al)" 按某种顺序组成。Goal 解析器会将 "G" 解释为字符串 "G"、"()" 解释为字符串 "o" ,"(al)" 解释为字符串 "al" 。然后,按原顺序将经解释得到的字符串连接成一个字符串。给你字符串 command ,返回 Goal 解析器 对 command 的解释结果。 + +## 解题思路 + +- 简单题,按照题意修改字符串即可。由于是简单题,这一题也不用考虑嵌套的情况。 + +## 代码 + +```go +package leetcode + +func interpret(command string) string { + if command == "" { + return "" + } + res := "" + for i := 0; i < len(command); i++ { + if command[i] == 'G' { + res += "G" + } else { + if command[i] == '(' && command[i+1] == 'a' { + res += "al" + i += 3 + } else { + res += "o" + i ++ + } + } + } + return res +} +``` \ No newline at end of file diff --git a/website/content/ChapterFour/1679.Max-Number-of-K-Sum-Pairs.md b/website/content/ChapterFour/1679.Max-Number-of-K-Sum-Pairs.md new file mode 100644 index 00000000..83ed4b31 --- /dev/null +++ b/website/content/ChapterFour/1679.Max-Number-of-K-Sum-Pairs.md @@ -0,0 +1,98 @@ +# [1679. Max Number of K-Sum Pairs](https://leetcode.com/problems/max-number-of-k-sum-pairs/) + + +## 题目 + +You are given an integer array `nums` and an integer `k`. + +In one operation, you can pick two numbers from the array whose sum equals `k` and remove them from the array. + +Return *the maximum number of operations you can perform on the array*. + +**Example 1:** + +``` +Input: nums = [1,2,3,4], k = 5 +Output: 2 +Explanation: Starting with nums = [1,2,3,4]: +- Remove numbers 1 and 4, then nums = [2,3] +- Remove numbers 2 and 3, then nums = [] +There are no more pairs that sum up to 5, hence a total of 2 operations. +``` + +**Example 2:** + +``` +Input: nums = [3,1,3,4,3], k = 6 +Output: 1 +Explanation: Starting with nums = [3,1,3,4,3]: +- Remove the first two 3's, then nums = [1,4,3] +There are no more pairs that sum up to 6, hence a total of 1 operation. +``` + +**Constraints:** + +- `1 <= nums.length <= 105` +- `1 <= nums[i] <= 109` +- `1 <= k <= 109` + +## 题目大意 + +给你一个整数数组 nums 和一个整数 k 。每一步操作中,你需要从数组中选出和为 k 的两个整数,并将它们移出数组。返回你可以对数组执行的最大操作数。 + +## 解题思路 + +- 读完题第一感觉这道题是 TWO SUM 题目的加强版。需要找到所有满足和是 k 的数对。先考虑能不能找到两个数都是 k/2 ,如果能找到多个这样的数,可以先移除他们。其次在利用 TWO SUM 的思路,找出和为 k 的数对。利用 TWO SUM 里面 map 的做法,时间复杂度 O(n)。 + +## 代码 + +```go +package leetcode + +// 解法一 优化版 +func maxOperations(nums []int, k int) int { + counter, res := make(map[int]int), 0 + for _, n := range nums { + counter[n]++ + } + if (k & 1) == 0 { + res += counter[k>>1] >> 1 + // 能够由 2 个相同的数构成 k 的组合已经都排除出去了,剩下的一个单独的也不能组成 k 了 + // 所以这里要把它的频次置为 0 。如果这里不置为 0,下面代码判断逻辑还需要考虑重复使用数字的情况 + counter[k>>1] = 0 + } + for num, freq := range counter { + if num <= k/2 { + remain := k - num + if counter[remain] < freq { + res += counter[remain] + } else { + res += freq + } + } + } + return res +} + +// 解法二 +func maxOperations_(nums []int, k int) int { + counter, res := make(map[int]int), 0 + for _, num := range nums { + counter[num]++ + remain := k - num + if num == remain { + if counter[num] >= 2 { + res++ + counter[num] -= 2 + } + } else { + if counter[remain] > 0 { + res++ + counter[remain]-- + counter[num]-- + } + } + } + return res +} +``` \ No newline at end of file diff --git a/website/content/ChapterFour/1680.Concatenation-of-Consecutive-Binary-Numbers.md b/website/content/ChapterFour/1680.Concatenation-of-Consecutive-Binary-Numbers.md new file mode 100644 index 00000000..b43a3e66 --- /dev/null +++ b/website/content/ChapterFour/1680.Concatenation-of-Consecutive-Binary-Numbers.md @@ -0,0 +1,95 @@ +# [1680. Concatenation of Consecutive Binary Numbers](https://leetcode.com/problems/concatenation-of-consecutive-binary-numbers/) + + +## 题目 + +Given an integer `n`, return *the **decimal value** of the binary string formed by concatenating the binary representations of* `1` *to* `n` *in order, **modulo*** `109 + 7`. + +**Example 1:** + +``` +Input: n = 1 +Output: 1 +Explanation: "1" in binary corresponds to the decimal value 1. +``` + +**Example 2:** + +``` +Input: n = 3 +Output: 27 +Explanation: In binary, 1, 2, and 3 corresponds to "1", "10", and "11". +After concatenating them, we have "11011", which corresponds to the decimal value 27. +``` + +**Example 3:** + +``` +Input: n = 12 +Output: 505379714 +Explanation: The concatenation results in "1101110010111011110001001101010111100". +The decimal value of that is 118505380540. +After modulo 109 + 7, the result is 505379714. +``` + +**Constraints:** + +- `1 <= n <= 10^5` + +## 题目大意 + +给你一个整数 n ,请你将 1 到 n 的二进制表示连接起来,并返回连接结果对应的 十进制 数字对 10^9 + 7 取余的结果。 + +## 解题思路 + +- 理解题意以后,先找到如何拼接最终二进制数的规律。假设 `f(n)` 为最终变换以后的十进制数。那么根据题意,`f(n) = f(n-1) << shift + n` 这是一个递推公式。`shift` 左移的位数就是 `n` 的二进制对应的长度。`shift` 的值是随着 `n` 变化而变化的。由二进制进位规律可以知道,2 的整数次幂的时候,对应的二进制长度会增加 1 位。这里可以利用位运算来判断是否是 2 的整数次幂。 +- 这道题另外一个需要处理的是模运算的法则。此题需要用到模运算的加法法则。 + + ```go + 模运算与基本四则运算有些相似,但是除法例外。 + (a + b) % p = (a % p + b % p) % p (1) + (a - b) % p = (a % p - b % p) % p (2) + (a * b) % p = (a % p * b % p) % p (3) + a ^ b % p = ((a % p)^b) % p (4) + 结合律: + ((a+b) % p + c) % p = (a + (b+c) % p) % p (5) + ((a*b) % p * c)% p = (a * (b*c) % p) % p (6) + 交换律: + (a + b) % p = (b+a) % p (7) + (a * b) % p = (b * a) % p (8) + 分配律: + ((a +b)% p * c) % p = ((a * c) % p + (b * c) % p) % p (9) + ``` + + 这一题需要用到模运算的加法运算法则。 + +## 代码 + +```go +package leetcode + +import ( + "math/bits" +) + +// 解法一 模拟 +func concatenatedBinary(n int) int { + res, mod, shift := 0, 1000000007, 0 + for i := 1; i <= n; i++ { + if (i & (i - 1)) == 0 { + shift++ + } + res = ((res << shift) + i) % mod + } + return res +} + +// 解法二 位运算 +func concatenatedBinary1(n int) int { + res := 0 + for i := 1; i <= n; i++ { + res = (res< k { + return -1 + } + } + orders := []int{} + for i := range counts { + orders = append(orders, i) + } + sort.Ints(orders) + res := math.MaxInt32 + generatePermutation1681(nums, counts, orders, 0, 0, eachSize, &res, []int{}) + if res == math.MaxInt32 { + return -1 + } + return res +} + +func generatePermutation1681(nums, counts, order []int, index, sum, eachSize int, res *int, current []int) { + if len(current) > 0 && len(current)%eachSize == 0 { + sum += current[len(current)-1] - current[len(current)-eachSize] + index = 0 + } + if sum >= *res { + return + } + if len(current) == len(nums) { + if sum < *res { + *res = sum + } + return + } + for i := index; i < len(counts); i++ { + if counts[order[i]] == 0 { + continue + } + counts[order[i]]-- + current = append(current, order[i]) + generatePermutation1681(nums, counts, order, i+1, sum, eachSize, res, current) + current = current[:len(current)-1] + counts[order[i]]++ + // 这里是关键的剪枝 + if index == 0 { + break + } + } +} +``` \ No newline at end of file diff --git a/website/content/menu/index.md b/website/content/menu/index.md index 7e525b22..a769bcc7 100644 --- a/website/content/menu/index.md +++ b/website/content/menu/index.md @@ -564,4 +564,8 @@ headless: true - [1663.Smallest-String-With-A-Given-Numeric-Value]({{< relref "/ChapterFour/1663.Smallest-String-With-A-Given-Numeric-Value.md" >}}) - [1664.Ways-to-Make-a-Fair-Array]({{< relref "/ChapterFour/1664.Ways-to-Make-a-Fair-Array.md" >}}) - [1665.Minimum-Initial-Energy-to-Finish-Tasks]({{< relref "/ChapterFour/1665.Minimum-Initial-Energy-to-Finish-Tasks.md" >}}) + - [1678.Goal-Parser-Interpretation]({{< relref "/ChapterFour/1678.Goal-Parser-Interpretation.md" >}}) + - [1679.Max-Number-of-K-Sum-Pairs]({{< relref "/ChapterFour/1679.Max-Number-of-K-Sum-Pairs.md" >}}) + - [1680.Concatenation-of-Consecutive-Binary-Numbers]({{< relref "/ChapterFour/1680.Concatenation-of-Consecutive-Binary-Numbers.md" >}}) + - [1681.Minimum-Incompatibility]({{< relref "/ChapterFour/1681.Minimum-Incompatibility.md" >}})