zoukankan      html  css  js  c++  java
  • 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
        }
    }
    
  • 相关阅读:
    2020-05-12 Linux基本操作
    SpringBoot项目设置能访问静态资源,resource/static目录下文件
    2020-04-25 Hadoop框架学习
    2020-05-24 vue简单语法
    2020-04-25 elasticsearch
    2020-04-25 kafka
    2020-04-11 函数式数据处理(Java8)
    2020-03-29 分布式事务解决方案(RocketMQ)
    配置文件示例
    Spring-data-redis实现消息队列的demo(附源码)
  • 原文地址:https://www.cnblogs.com/ganshuoos/p/12943710.html
Copyright © 2011-2022 走看看