1. 递增子序列
没有终止条件,因为要判断到最后一个元素,不能中途返回
路径上的后一个元素不能小于前一个元素
每层的元素也不能重复,用set去重(给定数组是无序的,不可排序)
class Solution {
List<Integer> path = new ArrayList<>();
List<List<Integer>> res = new ArrayList<>();
public List<List<Integer>> findSubsequences(int[] nums) {
backTracking(nums, 0);
return res;
}
public void backTracking(int[] nums, int start){
if(path.size() > 1){
res.add(new ArrayList<>(path));
}
Set<Integer> set = new HashSet<>();
for(int i = start; i < nums.length; i++){
if(!path.isEmpty() && nums[i] < path.get(path.size()-1) || set.contains(nums[i])){
continue;
}
set.add(nums[i]);
path.add(nums[i]);
backTracking(nums, i+1);
path.remove(path.size()-1);
}
}
}
- 时间复杂度: O(n * 2^n)
- 空间复杂度: O(n)
2. 全排列
每层遍历都是从第一个元素开始,但是不能包括路径中已经存在的元素
class Solution {
ArrayList<Integer> path = new ArrayList<>();
List<List<Integer>> res = new ArrayList<>();
public List<List<Integer>> permute(int[] nums) {
backTracking(nums);
return res;
}
public void backTracking(int[] nums){
if(path.size() == nums.length){
res.add(new ArrayList<>(path));
return;
}
for(int i = 0; i < nums.length; i++){
if(path.contains(nums[i]))
continue;
path.add(nums[i]);
backTracking(nums);
path.remove(path.size()-1);
}
}
}
3. 全排列 II
自己的思路:
set判断每层的元素是否重复
map(index,value)判断该路径上当前元素是否被用过(值相等,下标相等)
class Solution {
ArrayList<Integer> path = new ArrayList<>();
List<List<Integer>> res = new ArrayList<>();
Map<Integer, Integer> map = new HashMap<>();
public List<List<Integer>> permuteUnique(int[] nums) {
backTracking(nums);
return res;
}
public void backTracking(int[] nums){
if(path.size() == nums.length){
res.add(new ArrayList<>(path));
return;
}
Set<Integer> set = new HashSet<>();
for(int i = 0; i < nums.length; i++){
if(set.contains(nums[i]) || (map.get(i) != null && nums[i] == map.get(i)))
continue;
map.put(i, nums[i]);
path.add(nums[i]);
set.add(nums[i]);
backTracking(nums);
path.remove(path.size()-1);
map.remove(i);
}
}
}