排列组合
- 排列(不需要控制顺序,用 set 控制不选重复的数字)
[1,2,3], [3,2,1]
- 组合 (有顺序,通过index限制)
排列
- 全排列
- 全排列II(有重复数字)
[1, 1, 2]
- 基本结构:(各元素不同时)
使用 set 去除使用过的数字
- 去重复排列方式
- 先排序
- (i > 0 && nums[i] == nums[i-1] && !s.contains(i-1)) continue;
比如[1, 1, 2],要去除的是横向的节点,而纵向保留,纵向的 set 是会包含该数字,而横向不包含。
public void generator(int[] nums, List<Integer> tmp, HashSet<Integer> set, List<List<Integer>> res) {
if (tmp.size() == nums.length) {
res.add(new ArrayList<Integer>(tmp));
return;
}
for (int i = 0; i < nums.length; i++) {
if (set.contains(nums[i])) continue;
tmp.add(nums[i]);
set.add(nums[i]);
generator(nums, tmp, set, res);
tmp.remove(tmp.size() - 1);
set.remove(nums[i]);
}
}
组合
- 组合(不能用用过的元素,因此要使用 sort + index 的方式)
- 组合总和 II
- 基本结构:使用 sort + index 不生成相同组合
- 重复数字去重方式
if (i > index && candidates[i] == candidates[i-1]) continue;
index的核心内涵表示层数,第0层第1层第2层,而i则是从 index起开始取
public void helper(List<List<Integer>> res, List<Integer> tmp, int[] nums, int index) {
res.add(new ArrayList<>(tmp))
for (int i = index
if (i > index && nums[i] == nums[i-1]) continue
tmp.add(nums[i])
helper(res, tmp, nums, i + 1)
tmp.remove(tmp.size() - 1)
}
}