Combination Sum I&II Pernutation I&II

LeetCode的几道关于排列的题:

Combination Sum I

public class Solution {
    public List<List<Integer>> combinationSum(int[] candidates, int target) {
        List<List<Integer>>l=new ArrayList<>();
        if(null==candidates)return l;
        help(l,new ArrayList<Integer>(),0,target,candidates);
        return l;
    }//全排列的回溯算法有点和这个类似
    public void help(List<List<Integer>>l,List<Integer>t,int index,int target,int[] candidates){
        if(target==0){
            l.add(new ArrayList<Integer>(t));
            return;
        }
        if(target<0)return;
        for(int i=index;i<candidates.length;i++){
            t.add(candidates[i]);
            //关键就是下面这句索引到底是填index还是填i,关键还是要弄清函数是怎么走的
            //填i的话调用的时候会对一个位上的数字重复加,这也是题目需要的,故不能填i+1
            //填index的话就是求排列了,会出现和为相同数字的不同排序的case
            help(l,t,i,target-candidates[i],candidates);
            t.remove(t.size()-1);
        }
    }
}
Combination Sum II

public class Solution {
    public List<List<Integer>> combinationSum2(int[] candidates, int target) {
        List<List<Integer>>l=new ArrayList<>();
        if(candidates==null)return l;
        Arrays.sort(candidates);//排序的用处就是用来判断重复的case
        help(l,new ArrayList<Integer>(),0,target,candidates);
        return l;
    }
    
    public void help(List<List<Integer>>l,List<Integer>t,int index,int target,int[] nums){
        if(target==0){
            l.add(new ArrayList<Integer>(t));
            return;
        }
        if(target<0)return;
        for(int i=index;i<nums.length;i++){
           //和上面不同的就是简单的判断一个重复case
           //下面这句话的意思也就是和另外一个分支有相同的头,因为i!=index故目前就没有在一个分支的头节点,也就是处于index+k如此处的值和前面的有相同的,
           //就为重复case,就可以跳过
            if(i!=index&&nums[i]==nums[i-1])continue;
            t.add(nums[i]);
            help(l,t,i+1,target-nums[i],nums);
            t.remove(t.size()-1);
        }
    }
}

Permutation I

public class Solution {
    public List<List<Integer>> permute(int[] nums) {
        List<List<Integer>>l=new ArrayList<>();
        if(nums==null||nums.length==0){
            return l;
        }
        help(l,0,nums);
        return l;
    }
    
    public void help(List<List<Integer>>l,int index,int[] nums){
        if(index==nums.length){
            List<Integer>t=new ArrayList<>();
            for(int i:nums)t.add(i);
            l.add(t);
            return;
        }
        for(int i=index;i<nums.length;i++){
            swap(nums,i,index);
            //法1:使用数组拷贝的方法会浪费空间,也就是回到这个函数的状态还是以前的状态,调用其它函数更改的是副本
            help(l,index+1,Arrays.copyOf(nums,nums.length));
            //法2:会节约空间,每次返回都有此重置的过程
            help(l,index+1,nums);
            swap(nums,i,index);
        }
    }
    
    public void swap(int[] nums, int i, int j){
        int tmp=nums[i];
        nums[i]=nums[j];
        nums[j]=tmp;
    }
}

Permutaions II

public class Solution {
    public List<List<Integer>> permuteUnique(int[] nums) {
        List<List<Integer>>l=new ArrayList<>();
        Arrays.sort(nums);
        if(null==nums||nums.length==0)return l;
        help(l,0,nums);
        return l;
    }
    
    public void help(List<List<Integer>>l, int index,int[] nums){
        if(index==nums.length){
            List<Integer>t=new ArrayList<>();
            for(int i:nums)t.add(i);
            l.add(t);
        }
        for(int i=index;i<nums.length;i++){//和Combination SumII判断重复的思想相似
            //由于是和index处的值替换,故判断重复应该与index处的值判断重复
            if(i>index&&nums[i]==nums[index])continue;
            swap(nums,i,index);
            help(l,index+1,Arrays.copyOf(nums,nums.length));
        }
    }
    
    public void swap(int[] nums, int i,int j){
        int tmp=nums[i];
        nums[i]=nums[j];
        nums[j]=tmp;
    }
}




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值