Leetcode——组合总和

  • 用深信服的一个问题来引出此题:

题目描述: 给定一堆题目所对应的分值,请你从中挑选一些题目,使其分值正好是一百分

解题思路:

  • 将分值一个个加到一个列表中,一旦找到就输出列表
  • 否则将所有元素加入列表后,将其回溯,加入下一个元素
  • 可以在加入元素大于所要的100以后,就回溯
import java.util.List;
import java.util.ArrayList;

/*给定一堆题目所对应的分值,请你从中挑选一些题目,使其分值正好是一百分
 * coded by Jerome
 */
public class demo1 {
    public static List list = new ArrayList<>();
    public static List backtrack(int[] a,int target,int i){
        while(i list){
        int sum = 0;
        for(int x:list)
            sum += x;
        return sum;
    }
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        int[] a = {10,20,80,70};
        int target = 100;
        backtrack(a,target,0);
        //System.out.println(list);
    }

}
  • leetcode上的这题和上面这题的区别,其实就在于对于每个数字可以重复选择

  • 同时对于回溯的条件作了优化,一旦超过给定值,就回溯

题目描述:给定一个无重复元素的数组 candidates 和一个目标数 target ,找出 candidates 中所有可以使数字和为 target 的组合。candidates 中的数字可以无限制重复被选取。

说明:

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

解题思路:

  • 从array 里找到所有的组合,它的和是等于target的。任何组合只要是它的和等于target的话,都需要找到,但是不需要重复的。这道题中是可以重复利用一个数字的,那么我们就需要每次都代入同一个数字,直到它之和达到target 或者它超过了target, 然后在倒退回去一个数字,继续找下一个数字,这种情况肯定是要用递归了。这里是backtracking,每次倒退回一个数字,需要继续递归下去,在倒退,一直重复直到搜索了所有的可能性。
  • 举个例子分析

 [2,3,6,7]  target 7

  2                                  选2,sum = 2

  2+2                              选2,sum = 4

  2+2+2                          选2,sum = 6

  2+2+2+2                      选2,sum = 8 这时候 sum已经超出target,需要返回到上一个数字

  2+2+2+3                      选3,sum = 9, 也超出了target, 这里我们可以发现,如果是sorted array的话,从小到大,只要一                                              次超出,后面的数字必然也会超出target,所以可以在第一次超出的时候就直接跳出这一个迭代

  2+2+3                          选3,sum = 7,等于target, 此时返回并且跳出这一个迭代,因为后面的数字肯定超出(array里不                                                会有重复的数字)

  2+3                              选3,sum = 5,小于target,继续递归同一个数字

  2+3+3                          选3,sum = 8,超出target,返回上一个数字

  2+6                              选6,sum = 8,超出target,返回上一个数字

  3                                  选3,这里继续从3开始递归

  ...

  ...

  ...

class Solution {
        public List> combinationSum(int[] candidates, int target) {
            List> list = new ArrayList<>();
            Arrays.sort(candidates);
            backtrack(list,new ArrayList<>(),candidates,target,0);
            return list;
        }
        public static boolean backtrack(List> list,List temp,int[] a,int remain,int start){
            if(remain < 0)
                return false;
            if(remain == 0){
                list.add(new ArrayList(temp));
                return false;
            }
            else{
                for(int i = start;i

 

你可能感兴趣的:(Leetcode)