1、 组合和子集问题
组合问题需要满足一定要求才算作一个答案,比如数量要求(k个数),累加和要求(=target)。
子集问题是只要构成一个新的子集就算作一个答案。
进阶:去重逻辑。
- 一般都是要对同层去重。比如[1,1,2,2,2]
放置第一个位置的数时,如果已经使用过第一个1了,那么他的所有组合和子集一定包含第二个1
,所以去重逻辑就是同层不能出现相同的数
。
- 对于一个顺序数组,通常直接与前一个数比较即可。
for i in range(index+1, n):if i==index+1 or nums[i]!=nums[i-1]:dfs(i,[],target)
- 对于一个乱序数组,则需要用哈希表存储同层出现过的数。
hash = set()
for i in range(index+1, n):if i==index+1 or (nums[i] not in hash):hash.add(nums[i])dfs(i, [])
- 实际上上面的两段代码还蕴含了另一个去重,即
不同层不能用同一个下标的数
,所以这里索引时是从index+1开始。
2、分割问题
我们定义[start:end]
**(左闭右闭)**这段区间为分割出来的子串,对他进行条件判断。在python中对应的是s[start: end+1]
,end指向某个字符后面,表示切割到这个字符。start则为上一步的end+1。可以看下面这幅图,比较直观。理解了怎么分割字符串,剩下的就套回溯的模板就可以了。
def partition(self, s: str) -> List[List[str]]:n = len(s)res = []def ishuiwen(s):return s==s[::-1]def dfs(start,end,stack):ss = s[start:end+1]if not ishuiwen(ss):returnstack.append(ss)if end == n-1:res.append(stack.copy())return for i in range(end+1,n):dfs(end+1, i, stack.copy())for i in range(n):dfs(0, i, [])return res