491. Increasing Subsequences
- 思路
- dfs,backtrack
- 由于需要保证数组的顺序,这题不像[[90. Subsets II]]那般能sort,所以用了map来去重,
-
//java class Solution { List> result = new ArrayList(); LinkedList path = new LinkedList(); public List> findSubsequences(int[] nums) { helper(nums, 0); return result; } private void helper(int[] nums, int index){ if(path.size() >1){ result.add(new ArrayList(path)); } Map map = new HashMap(); for(int i = index; i< nums.length; i++){ if(!path.isEmpty() && nums[i] < path.get(path.size() - 1)){ continue; } if( map.getOrDefault(nums[i], 0) >= 1){ continue; } map.put(nums[i], map.getOrDefault(nums[i], 0)+1); path.add(nums[i]); helper(nums, i+1); path.removeLast(); } } }
46. Permutations
- 思路
- dfs backtrack
- permutation系列必须查重因为每次循环都是从0开始,且方法中没有其他类似startIndex的参数让数据自己叠加
- 因为每次都是从0开始,所以需要检查是否使用过这个数,以防同一个数多次使用
- 若添加了startIndex,而循环i=startIndex,会导致当startIndex=1的时候,nums[0]这个数永远取不到,导致path.size()少一位
-
[1,2,3] i = startIndex = 0; //can only get[1,2,3], [1,3,2] cannot get; i = 1 [2,3], [3,2] cannot get 1;
-
-
class Solution { List> result = new ArrayList(); LinkedList path = new LinkedList(); public List> permute(int[] nums) { helper(nums); return result; } private void helper(int[] nums){ if( path.size()==nums.length){ result.add(new ArrayList(path)); return; } for(int i = 0; i < nums.length; i++){ if(path.contains(nums[i])){ continue; } path.add(nums[i]); helper(nums); path.removeLast(); } } }
- 用[[47. Permutations II]]的模板也可以
- 不能用[[491. Increasing Subsequences]]中MAP(或者SET)的方法,这个方法是同层中去重用的,这里需要的是枝叶上去重.
-
//跟47 一毛一样,只是把判断跟之前数字重复部分删掉就行 class Solution { List> result = new ArrayList(); LinkedList path = new LinkedList(); public List> permute(int[] nums) { Arrays.sort(nums); boolean[] used = new boolean[nums.length]; helper(nums, used); return result; } private void helper(int[] nums, boolean[] used ){ if(path.size() == nums.length){ result.add(new ArrayList(path)); return; } for(int i = 0; i < nums.length; i++){ // if(i >0 && nums[i] == nums[i -1]&& !used[i-1]){ // continue; // } if(!used[i]){ path.add(nums[i]); used[i] = true; helper(nums, used); path.removeLast(); used[i] = false; } } } }
47. Permutations II
- 思路
- 这题用boolean[] used而不像之前[[40. Combination Sum II]] 与 [[90. Subsets II]]里那般可以用boolean mark
- 这里同时需要判断used[i-1]与used[i], 一个mark变量不够用
- 这里用for loop的第一个判断used[i-1]和!used[i-1]都可以
- used[i-1]判断本枝有没有重复
- !used[i-1]判断本层有没有重复
- 层判断更好,省时间
-
java class Solution { List> result = new ArrayList(); LinkedList path = new LinkedList(); public List> permuteUnique(int[] nums) { Arrays.sort(nums); boolean[] used = new boolean[nums.length]; helper(nums, used); return result; } private void helper(int[] nums, boolean[] used ){ if(path.size() == nums.length){ result.add(new ArrayList(path)); return; } for(int i = 0; i < nums.length; i++){ if(i >0 && nums[i] == nums[i -1]&& !used[i-1]){ continue; } if(!used[i]){ path.add(nums[i]); used[i] = true; helper(nums, used); path.removeLast(); used[i] = false; } } } }
- 这题用boolean[] used而不像之前[[40. Combination Sum II]] 与 [[90. Subsets II]]里那般可以用boolean mark