leetcode216组合总和III
找出所有相加之和为 n
的 k
个数的组合,且满足下列条件:
- 只使用数字1到9
- 每个数字 最多使用一次
返回 所有可能的有效组合的列表 。该列表不能包含相同的组合两次,组合可以以任何顺序返回。
思路:和之前做过的组合I大概思路是一样的,但是这道题多了一个 计算集合内的总和。
n代表我们k个数字的和,也就是k个数字相加==n
依然转化树形结构来看,k相当于树的深度,9相当于树的宽度,题目中说了只能是1-9的数字
选取过程如上图所示(来自代码随想录)
依然是递归三部曲:
终止条件:如果当前path长度达到k,然后path内元素的和==n,那么就加入结果集 并且return
递归参数:n,k,sum(调用的时候默认从0开始),startindex(下一层递归的位置)
单层循环逻辑:也就是一个循环遍历1-9的数字,然偶sum+=i.别忘了之前说过了。递归和回溯是一起的,有加就要有减,才可以回到上一层继续遍历其他的路。
然后开始递归
代码:
def combinationSum3(self, k: int, n: int) -> List[List[int]]:
res = []
path = []
def traceback(k,n,sum,startindex):
if len(path)==k:
if sum==n:
res.append(path[:])
return
for i in range(startindex,10):
path.append(i)
sum+=i
traceback(k,n,sum,i+1)
sum-=i
#回溯 有加就要减掉
path.pop()
traceback(k,n,0,1)
return res
"""递归三部曲:
终止条件:题目给出了k,n那么我们这个树的大小也就确定了。k就代表是树的深度。
n就是树的宽度。所以找到了k个数之后如果再往后找也就没有了其他多余的意义了。
传入参数:k,n,sum,startindex sum就是每个集合中元素的总和。
判断是不是等于N时候才会加入最后
的结果集。sum最后调用默认是从0开始的 startindex代表下一次递归是从哪里开始的
单程循环逻辑:既然确定是1-9中,那么sum每次就会+=i然后记录 是否等于n,在选择加不加入结果集
那么如果当前这个符合或者不符合,我们都需要回到上一层遍历其他的节点,
所以回溯在处理的时候如果有+
那么在递归之后就需要减。加了多少就要减多少 才回到上一层。
最后pop掉"""
Leetcode17电话号码的字母组合
给定一个仅包含数字 2-9
的字符串,返回所有它能表示的字母组合。答案可以按 任意顺序 返回。
给出数字到字母的映射如下(与电话按键相同)。注意 1 不对应任何字母。
最最最最暴力的方法,for循环嵌套。或者直接用python的内置函数iteral.product求笛卡尔乘积,学过sql的朋友应该不陌生,这道题就是类似sql的join然后求笛卡尔乘积
但是我们开始了回溯算法的章节,那么肯定要用回溯来写!
思路:首先需要创一个哈希表,数字和他所映射的字母 一 一 对应
然后依旧是转化为树形结构来看,如下图!
树的深度就是当前digits的长度,而最后的叶子节点就是我们要收集的结果,那么回溯出现在哪里呢?是不是最后一层找完了我们要继续回到上一层去找。
递归三部曲:
终止条件:如果index==len(digits),index就代表当前遍历的位置,如果index等于了当前digits的长度,那么就加入结果集并return
递归参数:首先需要一个字符串s来收集叶子节点的结果,然后用一个字符串数组result保存。也就是:s,digits,index
单层循环逻辑:首先找到当前要遍历digits中字母的位置,也就是map[digits[index]],index从0开始,获取到了第一个数字 然后再map中找到了这个数字映射的字母
for循环对这个数字指向的字母,s+=i,因为s是字符串哈!我们最后传入的时候是一个" ".
然后开始递归下一层,这里递归了之后是需要返回到上一层的,也就是s = s[:-1],这个就代表我们回溯到上一层的字母。然后继续遍历其他的字母。
这里递归我讲一下,主要是熟悉这个思路,至于递归里面的过程真的没有必要去扣出来,因为一不小心就会绕进去然后出不来,虽然我每次都被绕进去。。。。。
代码:
def letterCombinations(self, digits: str) -> List[str]:
result = []
def backtrace(digits,index,s:str):
map ={ '2':'abc',
'3':'def',
'4':'ghi',
'5':'jkl',
'6':'mno',
'7':'pqrs',
'8':'tuv',
'9':'wxyz'}
if not digits:
return []
if index==len(digits):
result.append(s)
return
letters = map[digits[index]]
for letter in letters:
s+=letter
backtrace(digits,index+1,s)
s=s[:-1]
backtrace(digits,0,'')
return result