第11天:递归、回溯
77. 组合
1、全部组合字眼,考虑回溯法。回溯法模板:(这里注意python中递归使用list时要用切片引用(浅复制),patch[:],而不用patch[]。很多题都是这样的,要用切片的浅复制。
时间复杂度:O(2^n)
空间复杂度:O(n + k) = O(n)O(n+k)=O(n),即递归使用栈空间的空间代价和临时数组temp 的空间代价。
这个时候我们可以做一个剪枝,如果当前path的大小为 s,未确定状态的区间 [starIndex,n] 的长度为 t,如果 s+t<k,那么即使 t 个都被选中,也不可能构造出一个长度为 k 的序列,故这种情况就没有必要继续向下递归,即我们可以在每次递归开始的时候做一次这样的判断:
if (path.size() + (n - starIndex + 1) < k) {
return;
}
void backtracking(参数) {
if (终止条件) {
存放结果; //result.append(path[:])
return;
}
for (选择:本层集合中元素(树中节点孩子的数量就是集合的大小)) {
处理节点; //path.append(i)
backtracking(路径,选择列表); // 递归
回溯,撤销处理结果 path.pop()
}
}
class Solution(object):
def combine(self, n, k):
"""
:type n: int
:type k: int
:rtype: List[List[int]]
"""
patch = []
result = []
def backtracking(n,k,startIndex):
if len(patch) == k:
result.append(patch[:])
return
for i in range(startIndex,n+1):
patch.append(i)
backtracking(n,k,i+1)
patch.pop()
backtracking(n,k,1)
return result
46.全排列
回溯法模板: 只是在对传递的参数修改,原来为index+1,这里是除了当前值外的nums值,(正是当前树层的子节点,如当前值为1,下一层就是2,3]。
class Solution(object):
def permute(self, nums):
"""
:type nums: List[int]
:rtype: List[List[int]]
"""
l = len(nums)
res = []
path = []
def backtracking(num):
if len(path) == l:
res.append(path[:])
return
for i in range(len(num)):
path.append(num[i])
t = [num[x] for x in range(len(num)) if x!= i]
backtracking(t)
path.pop()
backtracking(nums)
return res
784.字母大小写全排列
思路:
1、回溯法:但是不用for循环了(当前层的孩子节点要么是1要么是2,不是像“组合”题目一样数目是变化的,从n-1到n-2...到0),用if就行了。数字后面也要回溯,不能省略。
2、回溯法:用dfs写法,不用显示的写pop(),不用path,直接在参数中传入tmp+s[index],这样就避免对path做显示的出入栈操作了。
class Solution(object):
def letterCasePermutation(self, s):
"""
:type s: str
:rtype: List[str]
"""
path = []
res = []
l = len(s)
def backtracking(index):
if len(path[:]) == l:
res.append(''.join(path))
return
if '0'<= s[index] <='9' :
path.append(s[index])
backtracking(index+1)
path.pop()
else:
path.append(s[index].lower())
backtracking(index+1)
path.pop()
path.append(s[index].upper())
backtracking(index+1)
path.pop()
backtracking(0)
return res
class Solution(object):
def letterCasePermutation(self, s):
"""
:type s: str
:rtype: List[str]
"""
res = []
l = len(s)
def backtracking(tmp,index):
if len(tmp) == l:
res.append(tmp)
return
if '0' <= s[index] <= '9':
backtracking(tmp+s[index],index+1)
else:
backtracking(tmp+s[index].lower(),index+1)
backtracking(tmp+s[index].upper(),index+1)
backtracking('', 0)
return res