491. Non-decreasing Subsequences
非递减子序列。显然要用一个set来保存已经取过的元素。而且在本层内,元素取完不能再取,所以set需要是本地的。
另外要注意细节,题目要求返回的子序列至少两个元素。
class Solution {
public void backtracking(LinkedList<Integer> path, int[] nums, int pos, List<List<Integer>> res) {
if(path.size() >= 2) {
res.add(new LinkedList<Integer>(path));
}
Set<Integer> uset = new HashSet<Integer>();
for(int i=pos; i< nums.length; i++) {
if(!path.isEmpty() && nums[i] < path.peekLast()
|| uset.contains(nums[i])) {
continue;
}
uset.add(nums[i]);
path.add(nums[i]);
backtracking(path, nums, i+1, res);
path.removeLast();
}
}
public List<List<Integer>> findSubsequences(int[] nums) {
List<List<Integer>> res = new LinkedList<List<Integer>>();
LinkedList<Integer> path = new LinkedList<Integer>();
if(nums.length == 0) {
return res;
}
backtracking(path, nums, 0, res);
return res;
}
}
46. Permutations 排列题目以前刷过还记得。一条子树上要记录已经取过的元素,要么用全局变量,要么递归带一个额外的数组下去。
class Solution {
public void backtracking(LinkedList<Integer> path, Set<Integer> uset, int[] nums, List<List<Integer>> res) {
if(path.size() == nums.length) {
res.add(new LinkedList<Integer>(path));
return;
}
for(int i=0; i<nums.length; i++) {
if(uset.contains(nums[i])) {
continue;
}
path.add(nums[i]);
uset.add(nums[i]);
backtracking(path, uset, nums, res);
path.removeLast();
uset.remove(nums[i]);
}
}
public List<List<Integer>> permute(int[] nums) {
Set<Integer> uset = new HashSet<Integer>();
List<List<Integer>> res = new LinkedList<List<Integer>>();
LinkedList<Integer> path = new LinkedList<Integer>();
if(nums.length == 0) {
return res;
}
backtracking(path, uset, nums, res);
return res;
}
}
47. Permutations II 带去重的排列。但去重判断既可以true也可以false,我是没想过的。虽然第一次写的是按层去重,即
if (i > 0 && nums[i] == nums[i - 1] && used[i - 1] == false) {
continue;
}
但没想过也可以把true改为false也能过,只是变成了在树枝上去重。
if (i > 0 && nums[i] == nums[i - 1] && used[i - 1] == true) {
continue;
}
树层上去重(used[i - 1] == false),的树形结构如下:
树枝上去重(used[i - 1] == true)的树型结构如下:
class Solution {
boolean[] used;
public void backtracking(LinkedList<Integer> path, int[] nums, List<List<Integer>> res) {
if(path.size() == nums.length) {
res.add(new LinkedList<Integer>(path));
return;
}
for(int i=0; i<nums.length; i++) {
if(used[i] || (i>0 && nums[i] == nums[i-1] && !used[i-1])) {
continue;
}
used[i] = true;
path.add(nums[i]);
backtracking(path, nums, res);
path.removeLast();
used[i] = false;
}
}
public List<List<Integer>> permuteUnique(int[] nums) {
Arrays.sort(nums);
used = new boolean[nums.length];
List<List<Integer>> res = new LinkedList<List<Integer>>();
LinkedList<Integer> path = new LinkedList<Integer>();
if(nums.length == 0) {
return res;
}
backtracking(path, nums, res);
return res;
}
}