day29||回溯算法* 491.递增子序列* 46.全排列* 47.全排列 II

* 491.递增子序列

这道题我一开始没写对,但是有一点我需要注意到

如果if中的条件正着写很麻烦,那么你就反过来写。

举个例子,不针对这道题。

你看,上面带注释的就是正着写,我是希望i等于0和大于0而且nums[i]>=nums[i-1]的时候都执行如下函数,那不就是相当于i>0而且nums[i]小于nums[i-1]的时候就continue吗,多思考,会省下来很多步骤。。

class Solution {
    List<Integer> path = new ArrayList<>();
    List<List<Integer>> res = new ArrayList<>();
    public List<List<Integer>> findSubsequences(int[] nums) {
        boolean[] used = new boolean[nums.length]; 
        backTracking(nums,0,used);
        return res;
    }
    public void backTracking(int[] nums,int startIndex,boolean[] used){
        if(path.size()>=2){
            res.add(new ArrayList<>(path));
        }
        if(startIndex>=nums.length){
            return;
        }
        for(int i = startIndex;i<nums.length;i++){
            if(i>0&&nums[i]==nums[i-1]&&used[i-1]==false){
                continue;
            }
            // if(i==0){
            // path.add(nums[i]);
            // used[i]=true;
            // backTracking(nums,i+1,used);
            // used[i]=false;
            // path.remove(path.size()-1);
            // }
            // if(i>0&&nums[i]>=nums[i-1]){
            // path.add(nums[i]);
            // used[i]=true;
            // backTracking(nums,i+1,used);
            // used[i]=false;
            // path.remove(path.size()-1);
            // }else{
            //     continue;
            // }

if(i>0&&nums[i]<nums[i-1]){
    continue;
}else{
        path.add(nums[i]);
        used[i]=true;
        backTracking(nums,i+1,used);
        used[i]=false;
        path.remove(path.size()-1);
        }
        }
    }
}

下面是正确代码

我感觉if里面的终止条件写成!path.isEmpty()&&path.get(path.size()-1)>nums[i],我觉得比nums[i]<nums[i-1]的形式更好。。。

引入了新的去重方法哈希表uset。重点看一下。

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 startIndex){
        if(path.size()>1){
            res.add(new ArrayList<>(path));
        }
        HashSet<Integer> uset = new HashSet<>();
        for(int i = startIndex;i<nums.length;i++){
            if(!path.isEmpty()&&path.get(path.size()-1)>nums[i]||uset.contains(nums[i])){
                continue;
            }
            uset.add(nums[i]);
            path.add(nums[i]);
            backTracking(nums,i+1);
            path.remove(path.size()-1);
        }
    }
}

* 46.全排列

带注释的需要重点关注

class Solution {
    List<Integer> path = new ArrayList<>();
    List<List<Integer>> res = new ArrayList<>();
    
    public List<List<Integer>> permute(int[] nums) {
        boolean[] used = new boolean[nums.length];
        backTracking(nums,used);
        return res;
    }
    public void backTracking(int[] nums, boolean[] used){
        if(path.size()==nums.length){
            res.add(new ArrayList<>(path));
            return;
        }
        for(int i = 0;i<nums.length;i++){
            if(used[i] == true){
                continue;
            }
            path.add(nums[i]);
            used[i] = true;
            backTracking(nums,used);
            used[i] = false;
            path.remove(path.size()-1);
        }
    }
}

* 47.全排列 II

带注释的需要重点关注

class Solution {
    List<Integer> path = new ArrayList<>();
    List<List<Integer>> res = new ArrayList<>();
    public List<List<Integer>> permuteUnique(int[] nums) {
        boolean[] used = new boolean[nums.length];
        Arrays.sort(nums);/
        backTracking(nums,used);
        return res;
    }
    public void backTracking(int[] nums,boolean[] used){
        if(path.size()==nums.length){
            res.add(new ArrayList<>(path));
            return;
        }
        for(int i = 0;i<nums.length;i++){
            if(used[i]==true){
                continue;/
            }
            if(i>0&&nums[i]==nums[i-1]&&used[i-1]==false){
                continue;
            }
            // if (used[i] == false) {
            path.add(nums[i]);
            used[i]=true;
            backTracking(nums,used);
            path.remove(path.size()-1);
            used[i] = false;
            // }

        }
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值