491.递增子序列
见备注
int[] used
class Solution {
List<List<Integer>> res = new ArrayList<>();
List<Integer> path = new ArrayList<>();
//int[] used = new int[201];//元素取值从-100----100;
public List<List<Integer>> findSubsequences(int[] nums) {
backTracking(nums, 0);
return res;
}
private void backTracking(int[] nums, int startIndex) {
if(path.size() > 1) {//元素个数大于等于2
res.add(new ArrayList<>(path));
}
int[] used = new int[201];//元素取值从-100----100;//不能作为全局变量因为used标记的是每层元素是否重复 新递归时会创建新used数组进行新一轮的树层去重 树枝之间的used没有关联
for(int i = startIndex; i < nums.length; i++) {
if(!path.isEmpty() && nums[i] < path.get(path.size() - 1)) continue;//不能写成nums[i] < nums[i-1],因为path最后一个元素不一定是nums[i-1]
if(used[nums[i] + 100] == 1 ) continue;//树层去重
path.add(nums[i]);
used[nums[i] + 100] = 1;//不必回溯 因为used和树枝无关
backTracking(nums, i+1);
path.removeLast();
}
}
}
HashSet
class Solution {
List<List<Integer>> res = new ArrayList<>();
List<Integer> path = new ArrayList<>();
public List<List<Integer>> findSubsequences(int[] nums) {
backTracking(nums, 0);
return res;
}
private void backTracking(int[] nums, int startIndex) {
if(path.size() > 1) {//元素个数大于等于2
res.add(new ArrayList<>(path));
}
Set<Integer> set = new HashSet<>();
for(int i = startIndex; i < nums.length; i++) {
if(!path.isEmpty() && nums[i] < path.get(path.size() - 1)) continue;//不能写成nums[i] < nums[i-1],因为path最后一个元素不一定是nums[i-1]
if(set.contains(nums[i]) ) continue;//树层去重
path.add(nums[i]);
set.add(nums[i]);//不必回溯 因为used和树枝无关
backTracking(nums, i+1);
path.removeLast();
}
}
}
46.全排列
给定一个不含重复数字的数组 nums
,返回其 所有可能的全排列 。你可以 按任意顺序 返回答案。
class Solution {
List<List<Integer>> res = new ArrayList<>();
List<Integer> path = new LinkedList<>();
boolean[] used;
public List<List<Integer>> permute(int[] nums) {
used = new boolean[nums.length];
backTracking(nums);
return res;
}
private void backTracking(int[] nums) {
if(path.size() == nums.length) {
res.add(new ArrayList<>(path));
return;
}
for(int i = 0; i < nums.length; i++) {//从0开始循环
if(used[i]) continue;//树枝剪枝
used[i] = true;
path.add(nums[i]);
backTracking(nums);
path.removeLast();
used[i] = false;
}
}
}
47.全排列 II
给定一个可包含重复数字的序列 nums
,按任意顺序 返回所有不重复的全排列。
包括树枝去重和树层去重
class Solution {
List<List<Integer>> res = new ArrayList<>();
List<Integer> path = new LinkedList<>();
boolean[] used;
public List<List<Integer>> permuteUnique(int[] nums) {
Arrays.sort(nums);
used = new boolean[nums.length];
Arrays.fill(used, false);
backTracking(nums);
return res;
}
private void backTracking(int[] nums) {
if(path.size() == nums.length) {
res.add(new ArrayList<>(path));
return;
}
for(int i = 0; i < nums.length; i++) {//从0开始循环
// used[i - 1] == true,说明同⼀树⽀nums[i - 1]使⽤过
// used[i - 1] == false,说明同⼀树层nums[i - 1]使⽤过
if(used[i]) continue;//树枝剪枝
if(i > 0 && !used[i-1] && nums[i] == nums[i-1]) continue;//树层剪枝
used[i] = true;
path.add(nums[i]);
backTracking(nums);
path.removeLast();
used[i] = false;
}
}
}