[LeetCode] 39. 组合总和
题目链接 : 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);
}
}
}
类似题目还有:
这类题目都是同一类型的,用回溯算法!
其实回溯算法关键在于:不合适就退回上一步
然后通过约束条件, 减少时间复杂度.
大家可以从下面的解法找出一点感觉!
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
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
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
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
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
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. 组合总和的更多相关文章
- Java实现 LeetCode 39 组合总和
39. 组合总和 给定一个无重复元素的数组 candidates 和一个目标数 target ,找出 candidates 中所有可以使数字和为 target 的组合. candidates 中的数字 ...
- [leetcode] 39. 组合总和(Java)(dfs、递归、回溯)
39. 组合总和 直接暴力思路,用dfs+回溯枚举所有可能组合情况.难点在于每个数可取无数次. 我的枚举思路是: 外层枚举答案数组的长度,即枚举解中的数字个数,从1个开始,到target/ min(c ...
- leetcode 39 组合总和 JAVA
题目: 给定一个无重复元素的数组 candidates 和一个目标数 target ,找出 candidates 中所有可以使数字和为 target 的组合. candidates 中的数字可以无限制 ...
- LeetCode 39. 组合总和(Combination Sum)
题目描述 给定一个无重复元素的数组 candidates 和一个目标数 target ,找出 candidates 中所有可以使数字和为 target 的组合. candidates 中的数字可以无限 ...
- leetcode 39. 组合总和(python)
给定一个无重复元素的数组 candidates 和一个目标数 target ,找出 candidates 中所有可以使数字和为 target 的组合. candidates 中的数字可以无限制重复被选 ...
- LeetCode——39. 组合总和
给定一个无重复元素的数组 candidates 和一个目标数 target ,找出 candidates 中所有可以使数字和为 target 的组合. candidates 中的数字可以无限制重复被选 ...
- 【LeetCode】39. 组合总和
39. 组合总和 知识点:递归:回溯:组合:剪枝 题目描述 给定一个无重复元素的正整数数组 candidates 和一个正整数 target ,找出 candidates 中所有可以使数字和为目标数 ...
- Java实现 LeetCode 40 组合总和 II(二)
40. 组合总和 II 给定一个数组 candidates 和一个目标数 target ,找出 candidates 中所有可以使数字和为 target 的组合. candidates 中的每个数字在 ...
- LeetCode 中级 - 组合总和II(105)
给定一个数组 candidates 和一个目标数 target ,找出 candidates 中所有可以使数字和为 target 的组合. candidates 中的每个数字在每个组合中只能使用一次. ...
随机推荐
- 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 ...
- html acronym标签 语法
html acronym标签 语法 作用:定义首字母缩略词. 说明:如果首字母缩略词是一个单词,则可以被读出来,例如 NATO, NASA, ASAP, GUI.通过对只取首字母缩略词进行标记,您就能 ...
- 【CF1243D&CF920E】0-1 MST(bfs,set)
题意:给定一张n个点的完全图,其中有m条边权为1其余为0,求最小生成树的权值和 n,m<=1e5 思路:答案即为边权为0的边连接的联通块个数-1 用set存图和一个未被选取的点的集合,bfs过程 ...
- psdash-为开发、测试人员提供简单的方法,在web界面查看服务器的运行情况(网络,带宽,磁盘,CPU), 同时可以在web界面查看日志
psdash是linux的系统信息web指示板主要由使用数据psutil——由此得名. github地址:https://github.com/Jahaja/psdash 特性 安装 开始 配置 截图 ...
- Overview over available Turtle and Screen methods
24.5.2.1. Turtle methods Turtle motion Move and draw forward() | fd() backward() | bk() | back() rig ...
- C++二维数组(指针)做参数
一.问题描述 使用C++编程过程中经常需要使用到二维数组,然而初级程序员在使用过程中经常会出错使程序崩溃.下面就二维指针的定义,初始化,以及二维指针做参数给出简单介绍. 1.二维数组的定义与初始化 在 ...
- Elasticsear搭建
2.1:创建用户: (elasticsearch不能使用root用户) useradd angelpasswd angel 2.2:解压安装包 tar -zxvf elasticsearch-5.5. ...
- 响应式布局@media screen and ( max-width: 像素值 ) {}
设计思路很简单,首先先定义在标准浏览器下的固定宽度(假如标准浏览器的分辨率为1024px,那么我们设置宽为980px),然后用Media Query来监测浏览器的尺寸变化,当浏览器的分辨率小于1024 ...
- 利用IKVM在C#中调Java程序(总结+案例)
IKVM.NET是一个针对Mono和微软.net框架的java实现,其设计目的是在.NET平台上运行java程序.本文将比较详细的介绍这个工具的原理.使用入门(如何java应用转换为.NET应用.), ...
- 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 ...