Day22 | 78子集&90子集 II&46全排列&47全排列 II

104 阅读1分钟

子集 LeetCode 78

题目链接:[LeetCode 78 - 中等]

思路

子集问题和回溯的差异点在:result.add(new ArrayList(res));

回溯:

class Solution {
    List<List<Integer>> result = new ArrayList<>();
    List<Integer> res = new LinkedList<>();
    public List<List<Integer>> subsets(int[] nums) {
        backtracking(nums,0);
        return result;
    }
    private void backtracking(int[] nums,int startIndex){
        result.add(new ArrayList(res));
        if(startIndex >= nums.length){
            return;
        }
        for(int i=startIndex;i<nums.length;i++){
            res.addLast(nums[i]);
            backtracking(nums,i+1);
            res.removeLast();
        }
    }
}

子集 II LeetCode 90

题目链接:[LeetCode 90 - 中等]

思路

相较于子集,唯一的区别是:if(i>startIndex && nums[i]==nums[i-1]) continue;

回溯:

class Solution {
    List<List<Integer>> result = new ArrayList<>();
    List<Integer> res = new LinkedList<>();
    public List<List<Integer>> subsetsWithDup(int[] nums) {
        Arrays.sort(nums);
        backtracking(nums,0);
        return result;
    }
    private void backtracking(int[] nums,int startIndex){
        result.add(new ArrayList(res));
        if(startIndex >= nums.length){
            return;
        }
        for(int i=startIndex;i<nums.length;i++){
            if(i>startIndex && nums[i]==nums[i-1]) continue;
            res.addLast(nums[i]);
            backtracking(nums,i+1);
            res.removeLast();
        }
    }
}

全排列 LeetCode 46

题目链接:[LeetCode 46 - 中等]

思路

使用回溯即可

回溯:

class Solution {
    List<List<Integer>> result = new ArrayList<>();
    List<Integer> paths = new LinkedList<>();
    public List<List<Integer>> permute(int[] nums) {
        backtracking(nums,0);
        return result;
    }
    private void backtracking(int[] nums, int num){
        if(num == nums.length){
            result.add(new ArrayList(paths));
            return;
        }
        for(int i=0;i<nums.length;i++){
            int temp = nums[i];
            boolean flag = true;
            for(int j=0;j<num;j++){
                if(paths.get(j)==temp){
                    flag = false;
                    break;
                }
            }
            if(flag){
                paths.addLast(temp);
                backtracking(nums,num+1);
                paths.removeLast();
            }
        }
    }
}

使用LinkedList中的方法:

for (int i =0; i < nums.length; i++) {
            // 如果path中已有,则跳过
            if (path.contains(nums[i])) {
                continue;
            } 
            path.add(nums[i]);
            backtrack(nums, num+1);
            path.removeLast();
        }

全排列 LeetCode 47

题目链接:[LeetCode 47 - 中等]

思路

相较于子集和全排列,他无法在使用不用used数组的方式。

回溯:

class Solution {
    List<List<Integer>> result = new ArrayList<>();
    List<Integer> paths = new LinkedList<>();
    public List<List<Integer>> permuteUnique(int[] nums) {
        boolean[] used = new boolean[nums.length];
        Arrays.fill(used,false);
        Arrays.sort(nums);
        backtracking(nums,used);
        return result;
    }
        private void backtracking(int[] nums, boolean[] used){
        if(paths.size() == nums.length){
            result.add(new ArrayList(paths));
            return;
        }
        for(int i=0;i<nums.length;i++){
            if(i>0 && nums[i]==nums[i-1] && used[i-1]){
                continue;
            }
            if(!used[i]){
                used[i] = true;
                paths.add(nums[i]);
                backtracking(nums,used);
                paths.removeLast();
                used[i] = false;
            }

        }
    }
}