代码随想录算法训练营第27天 | 39. 组合总和,40. 组合总和 II,131. 分割回文串

代码随想录算法训练营第27天 | 39. 组合总和,40. 组合总和 II,131. 分割回文串

39. 组合总和

  1. 终止条件 当sum>=target时停止 若=就加入result
  2. for循环 中的 startindex 是用来控制 i 不要每次都从起点开始 因为组合问题 是不讲顺序的 5 2 和 2 5 是一样的
  3. 然后向下递归时 传入startindex 参数时 要看题目 是否可以重复值 若不可以 就传入i+1
class Solution {
    List<List<Integer>> result = new ArrayList<>();
    List<Integer> path = new ArrayList<>();

    public List<List<Integer>> combinationSum(int[] candidates, int target) {
        backtracing(0,candidates,target,0);
        return result;

    }

    public void backtracing(int sum,int[] candidates, int target, int index){
        //终止条件
        if(sum>=target){
            if(sum==target){
                result.add(new ArrayList(path));
                return;
            }else{
                return;
            }
        }


        for(int i=index;i<candidates.length;i++){
            sum+=candidates[i];
            path.add(candidates[i]);
            backtracing(sum,candidates,target,i);
            sum-=candidates[i];
            path.remove(path.size()-1);
        }
        return;
    }

    
}

40. 组合总和 II

  1. 输入数组中有重复元素 但是结果中不能有重复组合
  2. 可以将数组排序 创建一个标志数组 用来区分 每个元素是处于 树层还是处于树枝
  3. 在同一个树枝中 不需要去重
  4. 假若 相邻两个元素相等 并且前面一个元素 没有正在被用 那么就是树层去重 用continue跳过这个元素的递归
class Solution {
    List<List<Integer>> result = new ArrayList<>();
    List<Integer> path = new ArrayList<>();
    public List<List<Integer>> combinationSum2(int[] candidates, int target) {
        //构造一个标志数组 用来记录每个数的使用情况
        boolean[] used = new boolean[candidates.length];
        Arrays.fill(used,false);


        //对数组排序
        Arrays.sort(candidates);
        backtracing(0,candidates,target,0,used);
        return result;

    }

    public void backtracing(int sum, int[] candidates, int target, int startIndex, boolean[] used){
        //终止条件
        if(sum>=target){
            if(sum==target){
                result.add(new ArrayList<>(path));
                return;
            }else{
                return;
            }
        }

        //每层递归
        for(int i=startIndex;i<candidates.length;i++){
            //进行树层去重
            if(i>0 && candidates[i]==candidates[i-1] && used[i-1]==false){
                continue;
            }
            sum+=candidates[i];
            used[i]=true;
            path.add(candidates[i]);
            backtracing(sum,candidates,target,i+1,used);
            sum-=candidates[i];
            used[i]=false;
            path.remove(path.size()-1);
        }
        return;
    }
}

131. 分割回文串

  1. 每一段回文串可以用 startindex和i来切割
  2. 若为回文 就加入数组
  3. 判断回文串时 StringBuilder类 的 .reverse()会always true 都要转化成String .toString().equals()
class Solution {
    List<List<String>> result = new ArrayList<>();
    List<String> path = new ArrayList<>();
    public List<List<String>> partition(String s) {
        backtracing(s,0);
        return result;

    }

    //判断是否为回文串
    public static boolean isPalindrome(String s, int start, int end){
        s = s.substring(start,end+1);
        StringBuilder sb = new StringBuilder(s);
        //最后都转成字符串进行比较
        return sb.toString().equals(sb.reverse().toString());
    }
        


    public void backtracing(String s, int startIndex){
        //终止条件 当startindex大于字符串长度  说明找到了一组分割方案
        if(startIndex>=s.length()){
            result.add(new ArrayList<>(path));
            return;
        }


        //每层递归逻辑
        for(int i=startIndex;i<s.length();i++){
            //判断回文 若为回文则加入 path 
            if(isPalindrome(s,startIndex,i)){
                path.add(s.substring(startIndex,i+1));
            }else{
                continue;
            }
            
            backtracing(s,i+1);
            path.remove(path.size()-1);
        }
        return;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值