代码随想录 day 27

组合总和

给定一个无重复元素的数组 candidates 和一个目标数 target ,找出 candidates 中所有可以使数字和为 target 的组合。

candidates 中的数字可以无限制重复被选取。

说明:

  • 所有数字(包括 target)都是正整数。
  • 解集不能包含重复的组合。

示例 1:

  • 输入:candidates = [2,3,6,7], target = 7,
  • 所求解集为: [ [7], [2,2,3] ]

示例 2:

  • 输入:candidates = [2,3,5], target = 8,
  • 所求解集为: [ [2,2,2,2], [2,3,3], [3,5] ]

39. 组合总和 - 力扣(LeetCode)

回溯三部曲:

  • 递归函数参数:

数组,目标值,和,开始位置

void backTracking(int[] candidates, int target,int sum,int startIndex)
  • 递归终止条件
sum>target  不满足条件了直接走下次循环
sum==target  刚好满足,记录
  • 单层搜索的逻辑
   for (int i = startIndex; i < candidates.length; i++) {
            integerList.add(candidates[i]);
            sum+=candidates[i];
            //candidates 中的数字可以无限制重复被选取,所以下次是从i开始
            backTracking(candidates,target,sum,i);
            //回溯
            sum-=candidates[i];
            integerList.removeLast();
        }

代码

 private static  List<List<Integer>> list = new ArrayList<>();
    private static LinkedList<Integer> integerList = new LinkedList<>();
    public static List<List<Integer>> combinationSum(int[] candidates, int target) {
        backTracking(candidates,target,0,0);
        return list;
    }

    private static void backTracking(int[] candidates, int target,int sum,int startIndex) {
        if (sum>target){
            return;
        }
        if (sum==target){
            list.add(new ArrayList<>(integerList));
        }
        for (int i = startIndex; i < candidates.length; i++) {
            integerList.add(candidates[i]);
            sum+=candidates[i];
            backTracking(candidates,target,sum,i);
            sum-=candidates[i];
            integerList.removeLast();
        }
    }

组合总和II

给定一个数组 candidates 和一个目标数 target ,找出 candidates 中所有可以使数字和为 target 的组合。

candidates 中的每个数字在每个组合中只能使用一次。

说明: 所有数字(包括目标数)都是正整数。解集不能包含重复的组合。

  • 示例 1:
  • 输入: candidates = [10,1,2,7,6,1,5], target = 8,
  • 所求解集为:
[
  [1, 7],
  [1, 2, 5],
  [2, 6],
  [1, 1, 6]
]

40. 组合总和 II - 力扣(LeetCode)

和上一个差不多

重点:解集不能包含重复的组合

这里需要一个boolean[] used 用来标记数组元素是否使用

而且需要先对数组排序,因为不能重复组合,但相同元素是可以取到的

代码

private static  List<List<Integer>> list = new ArrayList<>();

private static LinkedList<Integer> integerList = new LinkedList<>();
static boolean[] used;

public static List<List<Integer>> combinationSum2(int[] candidates, int target) {
    used = new boolean[candidates.length];
    Arrays.fill(used, false);//填充数组
    Arrays.sort(candidates);
    backTracking(candidates,target,0,0);
    return list;
}
private static void backTracking(int[] candidates, int target,int sum,int startIndex) {
    if (sum>target){
        return;
    }
    if (sum==target){
        list.add(new ArrayList<>(integerList));
    }
    for (int i = startIndex; i < candidates.length; i++) {
        //这里是同一树层的去重,而不是不同数层的去重
        //排序后,同一数层,取相同元素时,会continue
        if (i>0&&candidates[i]==candidates[i-1]&&!used[i - 1]){
            continue;
        }
        integerList.add(candidates[i]);
        sum+=candidates[i];
        used[i]=true;
        backTracking(candidates,target,sum,i+1);
        sum-=candidates[i];
        used[i]=false;
        integerList.removeLast();
    }
}

分割回文串

给定一个字符串 s,将 s 分割成一些子串,使每个子串都是回文串。

返回 s 所有可能的分割方案。

示例: 输入: “aab” 输出: [ [“aa”,“b”], [“a”,“a”,“b”] ]

131. 分割回文串 - 力扣(LeetCode)

究极难,看了题解也是似懂非懂

 List<List<String>> list = new ArrayList<>();
    Deque<String> deque = new LinkedList<>();

    public List<List<String>> partition(String s) {
        backTracking(s, 0);
        return list;
    }

    private void backTracking(String s, int startIndex) {
        if (startIndex >= s.length()) {
            list.add(new ArrayList(deque));
            return;
        }
        for (int i = startIndex; i < s.length(); i++) {
            //如果是回文子串,则记录
            if (isPalindrome(s, startIndex, i)) {
                String str = s.substring(startIndex, i + 1);
                deque.addLast(str);
            } else {
                continue;
            }
            //起始位置后移,保证不重复
            backTracking(s, i + 1);
            deque.removeLast();
        }
    }
    private boolean isPalindrome(String s, int startIndex, int end) {
        for (int i = startIndex, j = end; i < j; i++, j--) {
            if (s.charAt(i) != s.charAt(j)) {
                return false;
            }
        }
        return true;
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值