题目链接 : https://leetcode-cn.com/problems/combination-sum/

题目描述:

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

思路:

回溯算法

很标准的模板


关注我的知乎专栏,了解更多解题技巧,大家一起加油!

代码:

python

class Solution:
def combinationSum(self, candidates: List[int], target: int) -> List[List[int]]:
candidates.sort()
n = len(candidates)
res = []
def helper(i, tmp_sum, tmp):
if tmp_sum > target or i == n:
return
if tmp_sum == target:
res.append(tmp)
return
helper(i, tmp_sum + candidates[i],tmp + [candidates[i]])
helper(i+1, tmp_sum ,tmp)
helper(0, 0, [])
return res

python

class Solution:
def combinationSum(self, candidates: List[int], target: int) -> List[List[int]]:
candidates.sort()
n = len(candidates)
res = []
def backtrack(i, tmp_sum, tmp):
if tmp_sum > target or i == n:
return
if tmp_sum == target:
res.append(tmp)
return
for j in range(i, n):
if tmp_sum + candidates[j] > target:
break
backtrack(j,tmp_sum + candidates[j],tmp+[candidates[j]])
backtrack(0, 0, [])
return res

java

class Solution {
public List<List<Integer>> combinationSum(int[] candidates, int target) {
List<List<Integer>> res = new ArrayList<>();
Arrays.sort(candidates);
//System.out.println(candidates);
backtrack(candidates, target, res, 0, new ArrayList<Integer>());
return res;
} private void backtrack(int[] candidates, int target, List<List<Integer>> res, int i, ArrayList<Integer> tmp_list) {
if (target < 0) return;
if (target == 0) {
res.add(new ArrayList<>(tmp_list));
return;
}
for (int start = i; start < candidates.length; start++) {
if (target < 0) break;
//System.out.println(start);
tmp_list.add(candidates[start]);
//System.out.println(tmp_list);
backtrack(candidates, target - candidates[start], res, start, tmp_list);
tmp_list.remove(tmp_list.size() - 1);
}
}
}

类似题目还有:

39.组合总和

40. 组合总和 II

46. 全排列

47. 全排列 II

78. 子集

90. 子集 II

这类题目都是同一类型的,用回溯算法!

其实回溯算法关键在于:不合适就退回上一步

然后通过约束条件, 减少时间复杂度.

大家可以从下面的解法找出一点感觉!

78. 子集

class Solution:
def subsets(self, nums):
if not nums:
return []
res = []
n = len(nums) def helper(idx, temp_list):
res.append(temp_list)
for i in range(idx, n):
helper(i + 1, temp_list + [nums[i]]) helper(0, [])
return res

90. 子集 II

class Solution(object):
def subsetsWithDup(self, nums):
"""
:type nums: List[int]
:rtype: List[List[int]]
"""
if not nums:
return []
n = len(nums)
res = []
nums.sort()
# 思路1
def helper1(idx, n, temp_list):
if temp_list not in res:
res.append(temp_list)
for i in range(idx, n):
helper1(i + 1, n, temp_list + [nums[i]])
# 思路2
def helper2(idx, n, temp_list):
res.append(temp_list)
for i in range(idx, n):
if i > idx and nums[i] == nums[i - 1]:
continue
helper2(i + 1, n, temp_list + [nums[i]]) helper2(0, n, [])
return res

46. 全排列

class Solution(object):
def permute(self, nums):
"""
:type nums: List[int]
:rtype: List[List[int]]
"""
if not nums:
return
res = []
n = len(nums)
visited = [0] * n
def helper1(temp_list,length):
if length == n:
res.append(temp_list)
for i in range(n):
if visited[i] :
continue
visited[i] = 1
helper1(temp_list+[nums[i]],length+1)
visited[i] = 0
def helper2(nums,temp_list,length):
if length == n:
res.append(temp_list)
for i in range(len(nums)):
helper2(nums[:i]+nums[i+1:],temp_list+[nums[i]],length+1)
helper1([],0)
return res

47. 全排列 II

class Solution(object):
def permuteUnique(self, nums):
"""
:type nums: List[int]
:rtype: List[List[int]]
"""
if not nums:
return []
nums.sort()
n = len(nums)
visited = [0] * n
res = [] def helper1(temp_list, length):
# if length == n and temp_list not in res:
# res.append(temp_list)
if length == n:
res.append(temp_list)
for i in range(n):
if visited[i] or (i > 0 and nums[i] == nums[i - 1] and not visited[i - 1]):
continue
visited[i] = 1
helper1(temp_list + [nums[i]], length + 1)
visited[i] = 0 def helper2(nums, temp_list, length):
if length == n and temp_list not in res:
res.append(temp_list)
for i in range(len(nums)):
helper2(nums[:i] + nums[i + 1:], temp_list + [nums[i]], length + 1) helper1([],0)
# helper2(nums, [], 0)
return res

39.组合总和

class Solution(object):
def combinationSum(self, candidates, target):
"""
:type candidates: List[int]
:type target: int
:rtype: List[List[int]]
"""
if not candidates:
return []
if min(candidates) > target:
return []
candidates.sort()
res = [] def helper(candidates, target, temp_list):
if target == 0:
res.append(temp_list)
if target < 0:
return
for i in range(len(candidates)):
if candidates[i] > target:
break
helper(candidates[i:], target - candidates[i], temp_list + [candidates[i]])
helper(candidates,target,[])
return res

40. 组合总和 II

class Solution:
def combinationSum2(self, candidates: List[int], target: int) -> List[List[int]]:
if not candidates:
return []
candidates.sort()
n = len(candidates)
res = [] def backtrack(i, tmp_sum, tmp_list):
if tmp_sum == target:
res.append(tmp_list)
return
for j in range(i, n):
if tmp_sum + candidates[j] > target : break
if j > i and candidates[j] == candidates[j-1]:continue
backtrack(j + 1, tmp_sum + candidates[j], tmp_list + [candidates[j]])
backtrack(0, 0, [])
return res

[LeetCode] 39. 组合总和的更多相关文章

  1. Java实现 LeetCode 39 组合总和

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

  2. [leetcode] 39. 组合总和(Java)(dfs、递归、回溯)

    39. 组合总和 直接暴力思路,用dfs+回溯枚举所有可能组合情况.难点在于每个数可取无数次. 我的枚举思路是: 外层枚举答案数组的长度,即枚举解中的数字个数,从1个开始,到target/ min(c ...

  3. leetcode 39 组合总和 JAVA

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

  4. LeetCode 39. 组合总和(Combination Sum)

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

  5. leetcode 39. 组合总和(python)

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

  6. LeetCode——39. 组合总和

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

  7. 【LeetCode】39. 组合总和

    39. 组合总和 知识点:递归:回溯:组合:剪枝 题目描述 给定一个无重复元素的正整数数组 candidates 和一个正整数 target ,找出 candidates 中所有可以使数字和为目标数  ...

  8. Java实现 LeetCode 40 组合总和 II(二)

    40. 组合总和 II 给定一个数组 candidates 和一个目标数 target ,找出 candidates 中所有可以使数字和为 target 的组合. candidates 中的每个数字在 ...

  9. LeetCode 中级 - 组合总和II(105)

    给定一个数组 candidates 和一个目标数 target ,找出 candidates 中所有可以使数字和为 target 的组合. candidates 中的每个数字在每个组合中只能使用一次. ...

随机推荐

  1. mysql-5.6.45-linux-glibc2.12-x86_64.tar.gz下载安装

    一 ,mysql下载 需要注册,可以通过组合url越过注册下载需要的包. 下载地址: https://dev.mysql.com/get/Downloads/MySQL-5.6/mysql-5.6.3 ...

  2. html acronym标签 语法

    html acronym标签 语法 作用:定义首字母缩略词. 说明:如果首字母缩略词是一个单词,则可以被读出来,例如 NATO, NASA, ASAP, GUI.通过对只取首字母缩略词进行标记,您就能 ...

  3. 【CF1243D&CF920E】0-1 MST(bfs,set)

    题意:给定一张n个点的完全图,其中有m条边权为1其余为0,求最小生成树的权值和 n,m<=1e5 思路:答案即为边权为0的边连接的联通块个数-1 用set存图和一个未被选取的点的集合,bfs过程 ...

  4. psdash-为开发、测试人员提供简单的方法,在web界面查看服务器的运行情况(网络,带宽,磁盘,CPU), 同时可以在web界面查看日志

    psdash是linux的系统信息web指示板主要由使用数据psutil——由此得名. github地址:https://github.com/Jahaja/psdash 特性 安装 开始 配置 截图 ...

  5. Overview over available Turtle and Screen methods

    24.5.2.1. Turtle methods Turtle motion Move and draw forward() | fd() backward() | bk() | back() rig ...

  6. C++二维数组(指针)做参数

    一.问题描述 使用C++编程过程中经常需要使用到二维数组,然而初级程序员在使用过程中经常会出错使程序崩溃.下面就二维指针的定义,初始化,以及二维指针做参数给出简单介绍. 1.二维数组的定义与初始化 在 ...

  7. Elasticsear搭建

    2.1:创建用户: (elasticsearch不能使用root用户) useradd angelpasswd angel 2.2:解压安装包 tar -zxvf elasticsearch-5.5. ...

  8. 响应式布局@media screen and ( max-width: 像素值 ) {}

    设计思路很简单,首先先定义在标准浏览器下的固定宽度(假如标准浏览器的分辨率为1024px,那么我们设置宽为980px),然后用Media Query来监测浏览器的尺寸变化,当浏览器的分辨率小于1024 ...

  9. 利用IKVM在C#中调Java程序(总结+案例)

    IKVM.NET是一个针对Mono和微软.net框架的java实现,其设计目的是在.NET平台上运行java程序.本文将比较详细的介绍这个工具的原理.使用入门(如何java应用转换为.NET应用.), ...

  10. leetcode-mid-sorting and searching - 240. Search a 2D Matrix II -NO

    mycode   time limited def searchMatrix(matrix, target): def deal(data): if not data: return False ro ...