-
Notifications
You must be signed in to change notification settings - Fork 44
/
_77_combine.java
83 lines (78 loc) · 2.26 KB
/
_77_combine.java
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
package pp.arithmetic.leetcode;
import pp.arithmetic.Util;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
/**
* Created by wangpeng on 2019-06-01.
* 77. 组合
* <p>
* 给定两个整数 n 和 k,返回 1 ... n 中所有可能的 k 个数的组合。
* <p>
* 示例:
* <p>
* 输入: n = 4, k = 2
* 输出:
* [
* [2,4],
* [3,4],
* [2,3],
* [1,2],
* [1,3],
* [1,4],
* ]
*
* @see <a href="https://leetcode-cn.com/problems/combinations/">combinations</a>
*/
public class _77_combine {
public static void main(String[] args) {
_77_combine combine = new _77_combine();
List<List<Integer>> lists = combine.combine(4, 2);
for (int i = 0; i < lists.size(); i++) {
Util.printList(lists.get(i));
}
}
/**
* 解题思路(回溯算法):
* 1.从list中开始取,一直取到k位
* 2.取的数放在一个list中,方便增减
* 3.取到k位后,回退到上一位,取没有取到的数字,直到全部取完
* <p>
* 注意不能重复[2,3]和[3,2]是一个组合,排序重复的办法:后面取的数必须比之前的大
* 优化点:可以去除一些不必要的循环,如循环的终止条件不是<=n,而是<=n-k+index
*
* @param n
* @param k
* @return
*/
public List<List<Integer>> combine(int n, int k) {
List<List<Integer>> retList = new ArrayList<>();
dfs(retList, new LinkedList<>(), 0, 1, n, k);
return retList;
}
/**
* DFS遍历
* @param retList 返回结果
* @param itemList 取数集合
* @param preNum 之前取的数
* @param index 当前第几位
* @param n n个数
* @param k 取k位
*/
private void dfs(List<List<Integer>> retList,
List<Integer> itemList,
int preNum,
int index,
int n,
int k) {
if (itemList.size() == k) {
retList.add(new LinkedList<>(itemList));
return;
}
for (int i = preNum + 1; i <= n - k + index; i++) {
itemList.add(i);
dfs(retList, itemList, i, index + 1, n, k);
itemList.remove(itemList.size() - 1);
}
}
}