leetcode刷题笔记三十九 组合总和

leetcode刷题笔记三十九 组合总和 与 四十 组合总和II

源地址:39. 组合总和

问题描述:

给定一个无重复元素的数组 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]
]

代码补充:

//因为需要对candidates中组合结果进行遍历,显然想到了回溯法,通过回溯剪枝的过程,通过target值判断回溯条件,当target值小于0时,回退;当target值等于0时,将当前记录的临时列表的数字放入到结果列表中;
//否则如果当前数字小于等于target值时,将其加入tempList,对target值进行修改,然后在剩余的candidates中查找
object Solution {
    var res:List[List[Int]] =  List[List[Int]]()
    def combinationSum(candidates: Array[Int], target: Int): List[List[Int]] = {
        res = List[List[Int]]()
        if (candidates.length == 0)  return List[List[Int]]()
        if (target < candidates.min) return List[List[Int]]()
        var tempList:List[Int] = List[Int]()

        def backtrack(candidates: Array[Int], target: Int, tempList:List[Int]):Unit = {
            if (target < 0) return
            if (target == 0) { res = res.::(tempList)}
            for ( i <- 0 to candidates.length-1  if candidates(i) <= target){

                backtrack(candidates.slice(i,candidates.length), target-candidates(i), tempList.+:(candidates(i)))
            }
        }
        backtrack(candidates, target, List[Int]())
        return res
    }
}

源地址:40. 组合总和 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]
]
示例 2:

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

代码补充:

//本题与前一题组合总和思路基本一致,都是通过回溯法对candidates进行遍历,与上一题不同的是,组合总和II允许重复数据,为了降低时间复杂度,需要对重复的candidate进行剪枝,具体做法是对原先的candidates进行排序,对相同数字只进行一次回溯,回溯范围是当前位置之后的数字
object Solution {
    var res = List[List[Int]]()
    def combinationSum2(candidates: Array[Int], target: Int): List[List[Int]] = {
            res = List[List[Int]]()
            if(candidates.length == 0) return List[List[Int]]()
            if(target < candidates.min) return List[List[Int]]()
            val candidateSorted =  candidates.sorted
    def backtrack(candidates:Array[Int], target:Int, tempList:List[Int]):Unit = {
            if(target < 0 ) return
            if(target == 0) res = res.+:(tempList)
            for(i <- 0 to candidates.length-1 if candidates(i) <= target ){
                if( i == 0 || candidates(i) != candidates(i-1)){
                backtrack(candidates.slice(i+1,candidates.length), target-candidates(i), tempList.:+(candidates(i)))
                }
            }
        }
        backtrack(candidateSorted.sorted, target, List[Int]())
        return res
    }
}
原文地址:https://www.cnblogs.com/ganshuoos/p/12943710.html