Skip to content

Commit 0a7a8db

Browse files
committed
add 39
1 parent 1dc85fd commit 0a7a8db

File tree

2 files changed

+146
-0
lines changed

2 files changed

+146
-0
lines changed
Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
1+
/*
2+
* @lc app=leetcode.cn id=39 lang=golang
3+
*
4+
* [39] 组合总和
5+
*
6+
* https://leetcode.cn/problems/combination-sum/description/
7+
*
8+
* algorithms
9+
* Medium (72.34%)
10+
* Likes: 2684
11+
* Dislikes: 0
12+
* Total Accepted: 829.3K
13+
* Total Submissions: 1.1M
14+
* Testcase Example: '[2,3,6,7]\n7'
15+
*
16+
* 给你一个 无重复元素 的整数数组 candidates 和一个目标整数 target ,找出 candidates 中可以使数字和为目标数 target
17+
* 的 所有 不同组合 ,并以列表形式返回。你可以按 任意顺序 返回这些组合。
18+
*
19+
* candidates 中的 同一个 数字可以 无限制重复被选取 。如果至少一个数字的被选数量不同,则两种组合是不同的。
20+
*
21+
* 对于给定的输入,保证和为 target 的不同组合数少于 150 个。
22+
*
23+
*
24+
*
25+
* 示例 1:
26+
*
27+
*
28+
* 输入:candidates = [2,3,6,7], target = 7
29+
* 输出:[[2,2,3],[7]]
30+
* 解释:
31+
* 2 和 3 可以形成一组候选,2 + 2 + 3 = 7 。注意 2 可以使用多次。
32+
* 7 也是一个候选, 7 = 7 。
33+
* 仅有这两种组合。
34+
*
35+
* 示例 2:
36+
*
37+
*
38+
* 输入: candidates = [2,3,5], target = 8
39+
* 输出: [[2,2,2,2],[2,3,3],[3,5]]
40+
*
41+
* 示例 3:
42+
*
43+
*
44+
* 输入: candidates = [2], target = 1
45+
* 输出: []
46+
*
47+
*
48+
*
49+
*
50+
* 提示:
51+
*
52+
*
53+
* 1 <= candidates.length <= 30
54+
* 2 <= candidates[i] <= 40
55+
* candidates 的所有元素 互不相同
56+
* 1 <= target <= 40
57+
*
58+
*
59+
*/
60+
package jzoffer
61+
62+
import (
63+
"fmt"
64+
"sort"
65+
)
66+
67+
// @lc code=start
68+
func combinationSumMy(candidates []int, target int) (res [][]int) {
69+
sort.Ints(candidates)
70+
visited := make(map[string]bool)
71+
var backtrace func(left int, path []int)
72+
backtrace = func(left int, path []int) {
73+
if left < 0 {
74+
return
75+
}
76+
if left == 0 {
77+
sort.Ints(path)
78+
if _, ok := visited[fmt.Sprintf("%v", path)]; ok {
79+
return
80+
}
81+
visited[fmt.Sprintf("%v", path)] = true
82+
// item := make([]int, len(path))
83+
// copy(item, path)
84+
res = append(res, path)
85+
return
86+
}
87+
for _, v := range candidates {
88+
if left-v < 0 {
89+
break
90+
}
91+
path = append(path, v)
92+
// 必须copy,否则会影响backtrace的递归
93+
p := make([]int, len(path))
94+
copy(p, path)
95+
backtrace(left-v, p)
96+
path = path[:len(path)-1]
97+
}
98+
}
99+
backtrace(target, []int{})
100+
return
101+
}
102+
103+
// 作者:ukcuf
104+
// 链接:https://leetcode.cn/problems/combination-sum/
105+
// 来源:力扣(LeetCode)
106+
// 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
107+
func combinationSum(candidates []int, target int) [][]int {
108+
sort.Ints(candidates)
109+
return dfs(candidates, target)
110+
}
111+
112+
func dfs(candidates []int, target int) [][]int {
113+
ret := [][]int{}
114+
for i, d := range candidates {
115+
if target-d < 0 {
116+
break
117+
} else if target-d == 0 {
118+
ret = append(ret, []int{d})
119+
continue
120+
}
121+
for _, v := range dfs(candidates[i:], target-d) {
122+
ret = append(ret, append([]int{d}, v...))
123+
}
124+
}
125+
return ret
126+
}
127+
128+
// @lc code=end

go/backtracking/39/39_test.go

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
package jzoffer
2+
3+
import (
4+
"fmt"
5+
"testing"
6+
)
7+
8+
func Test39(t *testing.T) {
9+
var (
10+
a = [4]int{1, 2, 3}
11+
b = [4]int{1, 2, 3, 4}
12+
c = [4]int{1, 2, 3}
13+
)
14+
fmt.Println(a, b, c, a == b, a == c, b == c)
15+
16+
fmt.Println(combinationSum([]int{7, 3, 2}, 18))
17+
fmt.Println(combinationSum([]int{2, 3, 6, 7}, 7))
18+
}

0 commit comments

Comments
 (0)