-
Notifications
You must be signed in to change notification settings - Fork 1
/
216_combination_sum_III_test.go
129 lines (102 loc) · 2.4 KB
/
216_combination_sum_III_test.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
package _6_backtracking
import (
"github.com/smartystreets/goconvey/convey"
"testing"
)
// 组合总和III :https://leetcode.cn/problems/combination-sum-iii/solutions/2071013/hui-su-bu-hui-xie-tao-lu-zai-ci-pythonja-feme/
func TestCombination3(t *testing.T) {
convey.Convey("组合总和 III:相加之和为 n 的 k 个数的组合,只使用数字1到9,每个数字 最多使用一次 ", t, func() {
testCase := []struct {
input struct {
k int
n int
}
target [][]int
}{
{
struct {
k int
n int
}{n: 7, k: 3}, [][]int{{1, 2, 4}},
},
{
struct {
k int
n int
}{n: 9, k: 3}, [][]int{
{1, 2, 6},
{1, 3, 5},
{2, 3, 4},
},
},
{
struct {
k int
n int
}{n: 1, k: 4}, [][]int{},
},
}
for _, tst := range testCase {
rsp := combinationSumIII_1(tst.input.k, tst.input.n)
compareRsp := intSliceSliceEqual(rsp, tst.target)
convey.So(compareRsp, convey.ShouldBeTrue)
}
})
}
// 方式二:多几个剪枝
// 元素和超过 n 优化
// 元素和选择最大前几个小于 n 优化
func combinationSumIII_2(k int, n int) [][]int {
var ans = make([][]int, 0)
var dfs func(i, t int)
var path = make([]int, 0)
dfs = func(i, t int) { // t 代表目标值
m := len(path)
d := k - m // 还要选 d 个数
// 这里进行剪枝优化
if t < 0 || t > (i+i-d+1)*d/2 { // 剩余选择最大的
return
}
if d == 0 { // 上面可以判断 t<0 || t>0
ans = append(ans, append([]int(nil), path...)) // 记录答案
return
}
for j := i; j >= d; j-- { // 这里的意思就是 d>=i
path = append(path, j)
dfs(j-1, t-j)
// 返回恢复现场
path = path[:len(path)-1]
}
}
dfs(9, n)
return ans
}
// 方法一:枚举下一个数选哪个
func combinationSumIII_1(k int, n int) [][]int {
var ans = make([][]int, 0)
var dfs func(i int)
var path = make([]int, 0)
dfs = func(i int) {
m := len(path)
d := k - m // 还要选 d 个数
if d == 0 {
// 相比 77 组合 https://leetcode.cn/problems/combinations/description/ 简单多个判断
var sum int
for _, v := range path {
sum += v
}
if sum == n {
ans = append(ans, append([]int(nil), path...)) // 记录答案
}
return
}
for j := i; j >= d; j-- { // 这里的意思就是 d>=i
path = append(path, j)
dfs(j - 1)
// 返回恢复现场
path = path[:len(path)-1]
}
}
dfs(9)
return ans
}