算法Day21 | Leetcode93.复原IP地址、78.子集、90.子集II

93.复原IP地址

力扣链接

思路

回溯,确定返回条件(1.只能打四个点 2.题目给了是0-255),且题目说了,第一个数字是0的话后面必须打点(即continue),正常回溯划分就行

代码

class Solution {
    List<List<Integer>> result=new ArrayList<>();
    List<Integer> path=new ArrayList<>();
    public List<List<Integer>> combine(int n, int k) {
        find(1,n,k);
        return result;
    }

    public void find(int startIndex,int n,int k){
        if(path.size()==k){
            result.add(new ArrayList<>(path));
            return;
        }

        for(int i=startIndex;i<=n-(k-path.size())+1;i++){
            path.add(i);
            find(i+1,n,k);
            path.removeLast();
        }
    }
}

78.子集

力扣链接

思路

回溯,因为元素各不相同,所以无需排序去重。跟之前不同的是,我们的起始循环一直是从0开始而不是startIndex,因为这是找各种组合(通过标记数组表示使用过就行),且只要进来就将路径集加入结果集中

代码

class Solution {
    List<List<Integer>> result=new ArrayList<>();
    List<Integer> path=new ArrayList<>();
    public List<List<Integer>> subsets(int[] nums) {
        //Arrays.sort(nums);
        find(nums,0);
        return result;
    }

    public void find(int[] nums,int startIndex){
        result.add(new ArrayList<>(path));
        if(startIndex>=nums.length) return;

        for(int i=startIndex;i<nums.length;i++){
            path.add(nums[i]);
            find(nums,i+1);
            path.remove(path.size()-1);
        }
    }
}

90.子集II

力扣链接

思路

回溯,因为元素变得可重复了,所以为了保证组合不重复,将数组做排序(同样的,如果当前元素跟前一个元素相同,并且前一个元素处于未使用状态,说明这两情况相同(而非是同时取两个的情况),continue跳过),跟上面不一样,上面不重复所以不排序,从0开始循环,但是这题排了序了,那就以startIndex往后,不然就出现重复组合了。

代码

class Solution {
    List<List<Integer>> result=new ArrayList<>();
    List<Integer> path=new ArrayList<>();
    int[] hasUsed;
    public List<List<Integer>> subsetsWithDup(int[] nums) {
        hasUsed=new int[nums.length];
        Arrays.sort(nums);
        find(nums,0);
        return result;
    }

    public void find(int[] nums,int startIndex){
        result.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] && hasUsed[i-1]==0) continue;
            path.add(nums[i]);
            hasUsed[i]=1;
            find(nums,i+1);
            path.remove(path.size()-1);
            hasUsed[i]=0;
        }
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值