Leetcode078、90(子集问题)———回溯算法(判断添加结果条件)

地址:

Leetcode078:

Leetcode090:

描述:

 题解:

主要思路:

代码(一):

注意点:

 代码(二):


地址:

Leetcode078:

https://leetcode-cn.com/problems/subsets/

Leetcode090:

https://leetcode-cn.com/problems/subsets-ii/

描述:

 

 题解:

https://leetcode-cn.com/problems/subsets/solution/dai-ma-sui-xiang-lu-78-zi-ji-hui-su-sou-6yfk6/

解题思路第二题其实也是考核我们对于剪枝思想的掌握,如果忘记了可以看我之前写的全排列二

https://blog.csdn.net/qq_52934831/article/details/119578852

主要思路:

78.子集

从图中红线部分,可以看出遍历这个树的时候,把所有节点都记录下来,就是要求的子集集合

代码(一):

class Solution {
   //存放最终结果
    List<List<Integer>> subsets=new ArrayList<>();
    //存放其中一种
    List<Integer> temp=new ArrayList<>();
    public List<List<Integer>> subsets(int[] nums) {
    backtracking(nums,0);
    return subsets;
    }
    public void backtracking (int []nums,int index){
        subsets.add(new ArrayList<>(temp));
        for(int i=index;i<nums.length;i++){
            temp.add(nums[i]);
            //错误示范:
            //backtracking(nums,index+1);
            backtracking(nums,i+1);
            temp.remove(temp.size()-1);
        }
    }
}

注意点:

 

 一开始我是这么写的,这样有问题的原因在于,当我们取用一个数以后我们只能使用它后面的数字,所以要取i+1;

说实话我不是很清楚index+1错在哪里,不过我倒是能通过debug找出它错误的执行顺序,是这样的:

 代码(二):

class Solution {
   //存放最终结果
    List<List<Integer>> subsetsWithDup=new ArrayList<>();
    //存放其中一种
    List<Integer> temp=new ArrayList<>();
    public List<List<Integer>> subsetsWithDup(int[] nums) {
        //先排序
        for(int i=0;i<nums.length-1;i++){
            for(int j=0;j<nums.length-i-1;j++){
                if(nums[j]>nums[j+1]){
                    int temp=nums[j];
                    nums[j]=nums[j+1];
                    nums[j+1]=temp;
                }
            }
        }
        boolean []exist=new boolean [nums.length];
        backtracking(nums,0,exist);
        return subsetsWithDup;
    }
    public void backtracking (int []nums,int index,boolean exist[]){
        subsetsWithDup.add(new ArrayList<>(temp));
        for(int i=index;i<nums.length;i++){
            if(i>0&&nums[i]==nums[i-1]&&!exist[i-1]) continue;
            temp.add(nums[i]);
            exist[i]=true;
            backtracking(nums,i+1,exist);
            temp.remove(temp.size()-1);
            exist[i]=false;
        }
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值