1、复原IP地址
class Solution:
def restoreIpAddresses(self, s: str) -> List[str]:
def isValid(s): # 判断地址是否合法 <256 且没有前置0
return int(s) < 256 and (s[0] != '0' or s == '0')
def back(s, start, dotNum, path, result):
if dotNum == 4: # 如果打了四个点,说明有了四段,可以返回了
if start == len(s): # 如果start到了s的最后一位,说明整个IP复合要求
result.append('.'.join(path))
return
for i in range(1, 4): # IP地址从1位遍历到3位
if start + i > len(s):
break
segment = s[start:start+i] # 分割
if isValid(segment): # 判断分割的地址是否符合,符合的话进入下一层
path.append(segment)
back(s, start+i, dotNum+1, path, result)
#回溯
path.pop()
result = []
back(s, 0, 0, [], result)
return result
2、子集
class Solution:
def back(self, nums, idx, path, result):
result.append(path[:]) # 在每个节点都收集结果,这题的精髓所在
if idx >= len(nums): # 这里可写可不写,反正for跑完了就会return
return
for i in range(idx, len(nums)): # 和组合的回溯法差不多
path.append(nums[i])
self.back(nums, i+1, path, result)
path.pop()
def subsets(self, nums: List[int]) -> List[List[int]]:
result = []
self.back(nums, 0, [] ,result)
return result
3、子集II
class Solution:
def subsetsWithDup(self, nums: List[int]) -> List[List[int]]:
def back(nums, startId, used, path, result):
result.append(path[:])
if startId >= len(nums):
return
for i in range(startId, len(nums)):
if i > 0 and nums[i] == nums[i-1] and not used[i-1]:
continue
path.append(nums[i])
# 在上一题的基础上加入used数组树层去重
# 结合前两天的知识点
used[i] = True
back(nums, i+1, used, path, result)
path.pop()
used[i] = False
nums.sort()
used = [False]*len(nums)
result = []
back(nums, 0, used, [], result)
return result