代码随想录算法训练营第二十八天|93. 复原 IP 地址,78. 子集,90. 子集 II
93. 复原 IP 地址
【注意】
1.切割问题就可以使用回溯搜索法把所有可能性搜出来。
2.startIndex一定是需要的,因为不能重复分割,记录下一层递归分割的起始位置。
3.本题我们还需要一个变量pointNum,记录添加逗点的数量。
4.分割的段数作为终止条件。pointNum表示逗点数量(决定了树的深度),pointNum为3说明字符串分成了4段了。
5.循环中 [startIndex, i] 这个区间就是截取的子串,需要判断这个子串是否合法。如果合法就在字符串后面加上符号.表示已经分割。
6.左闭右闭。
【代码】
1 class Solution(object): 2 def __init__(self): 3 self.result = [] 4 def restoreIpAddresses(self, s): 5 """ 6 :type s: str 7 :rtype: List[str] 8 """ 9 ''' 10 本质切割问题使用回溯搜索法,本题只能切割三次,所以纵向递归总共四层 11 因为不能重复分割,所以需要start_index来记录下一层递归分割的起始位置 12 添加变量point_num来记录逗号的数量[0,3] 13 ''' 14 if len(s) > 12: 15 return [] 16 #递归回溯 17 self.backtracking(s,0,0) 18 return self.result 19 20 def backtracking(self,s,start_index,point_num): 21 if point_num == 3: 22 if self.is_valid(s, start_index, len(s)-1):#判断最后一个子串段是否满足 23 self.result.append(s[:]) 24 return 25 26 for i in range(start_index, len(s)): 27 # [start_index, i]就是被截取的子串 28 if self.is_valid(s, start_index, i): 29 s = s[:i+1]+'.'+s[i+1:] 30 # 在填入.后,下一子串起始后移2位 31 self.backtracking(s,i+2,point_num+1) 32 # 回溯 33 s = s[:i+1]+s[i+2:] 34 else: 35 # 若当前被截取的子串大于255或者大于三位数,直接结束本层循环 36 break 37 38 def is_valid(self,s,start,end): 39 if start > end: 40 return False 41 # 若数字是0开头,不合法 42 if s[start] == '0' and start != end: 43 return False 44 if not 0 <= int(s[start:end+1]) <= 255: 45 return False 46 return True
78. 子集
【注意】
1.组合问题和分割问题都是收集树的叶子节点,而子集问题是找树的所有节点!
2.剩余集合为空的时候,就是叶子节点。就是startIndex已经大于数组的长度了,就终止了,因为没有元素可取了。
3.求取子集问题,不需要任何剪枝!因为子集就是要遍历整棵树。
【代码】
1 class Solution(object): 2 def __init__(self): 3 self.path = [] 4 self.paths = [] 5 6 def subsets(self, nums): 7 """ 8 :type nums: List[int] 9 :rtype: List[List[int]] 10 """ 11 self.backtracking(nums, 0) 12 return self.paths 13 14 def backtracking(self, nums, start_index): 15 # 收集子集,要先于终止判断 16 self.paths.append(self.path[:]) 17 # Base Case 18 if start_index == len(nums): 19 return 20 21 # 单层递归逻辑 22 for i in range(start_index, len(nums)): 23 self.path.append(nums[i]) 24 self.backtracking(nums, i+1) 25 self.path.pop() # 回溯
90. 子集 II
【注意】
1.去重。
【代码】
1 class Solution(object): 2 def __init__(self): 3 self.path = [] 4 self.paths = [] 5 def subsetsWithDup(self, nums): 6 """ 7 :type nums: List[int] 8 :rtype: List[List[int]] 9 """ 10 #通过start_index进行去重 11 #先对数组进行排序 12 nums.sort() 13 self.backtracking(nums,0) 14 return self.paths 15 16 def backtracking(self, nums, start_index): 17 # 收集子集,要先于终止判断 18 self.paths.append(self.path[:]) 19 if start_index == len(nums): 20 return 21 22 for i in range(start_index, len(nums)): 23 #数层去重: 24 if i > start_index and nums[i] == nums[i-1]: 25 continue 26 self.path.append(nums[i]) 27 self.backtracking(nums, i+1) 28 self.path.pop()
浙公网安备 33010602011771号