代码随想录算法训练营第24天 | 93.复原IP地址 78.子集 90.子集Ⅱ
93.复原IP地址
给定一个只包含数字的字符串,复原它并返回所有可能的 IP 地址格式。
有效的 IP 地址 正好由四个整数(每个整数位于 0 到 255 之间组成,且不能含有前导 0),整数之间用 '.' 分隔。
例如:"0.1.2.201" 和 "192.168.1.1" 是 有效的 IP 地址,但是 "0.011.255.245"、"192.168.1.312" 和 "192.168@1.1" 是 无效的 IP 地址。
解题
1.递归参数:
startIndex一定是需要的,因为不能重复分割,记录下一层递归分割的起始位置。
2.终止条件:
终止条件和131.分割回文串情况就不同了,本题明确要求只会分成4段,所以不能用切割线切到最后作为终止条件,而是分割的段数作为终止条件。
然后验证一下第四段是否合法,如果合法就加入到结果集里
3.单层搜索的逻辑:
在for (int i = startIndex; i < s.size(); i++)循环中 [startIndex, i] 这个区间就是截取的子串,需要判断这个子串是否合法。
点击查看代码
class Solution:
def restoreIpAddresses(self, s: str) -> List[str]:
result=[]
self.backtracking(s,0,0,[],result)
return result
def backtracking(self,s,startIndex,pointNum,path,result):
if pointNum==3:
if self.is_valid(s,startIndex,len(s)-1):
result.append('.'.join(path+[s[startIndex:]]))
return
for i in range(startIndex,len(s)):
if self.is_valid(s,startIndex,i):
sub=s[startIndex:i+1]
path.append(sub)
pointNum+=1
self.backtracking(s,i+1,pointNum,path,result)
pointNum-=1
path.pop()
else:
break
def is_valid(self,s,start,end):
if start>end:
return False
if s[start]=='0' and start!=end:
return False
if 0<=int(s[start:end+1])<=255:
return True
78.子集
给定一组不含重复元素的整数数组 nums,返回该数组所有可能的子集(幂集)。
说明:解集不能包含重复的子集。
解题
可以不需要加终止条件,因为startIndex >= nums.size(),本层for循环本来也结束了。
报错:1.递归里是i+1不是startIndex+1;2.添加结果时用path[:]浅拷贝添加path的当前状态,不是直接用path
点击查看代码
class Solution:
def subsets(self, nums: List[int]) -> List[List[int]]:
result=[]
self.backtracking(nums,0,[],result)
return result
def backtracking(self,nums,startIndex,path,result):
result.append(path[:])
for i in range(startIndex,len(nums)):
path.append(nums[i])
self.backtracking(nums,i+1,path,result)
path.pop()
90.子集Ⅱ
给定一个可能包含重复元素的整数数组 nums,返回该数组所有可能的子集(幂集)。
说明:解集不能包含重复的子集。
解题
利用used数组进行树层的去重,nums和i-1的元素相同并且i-1的used是False,背题就完事了!
题目和上一道差不多,去重思路和昨天的40也一样。
点击查看代码
class Solution:
def subsetsWithDup(self, nums: List[int]) -> List[List[int]]:
result=[]
nums.sort()
used=[False]*len(nums)
self.backtracking(nums,0,used,[],result)
return result
def backtracking(self,nums,startIndex,used,path,result):
result.append(path[:])
for i in range(startIndex,len(nums)):
if i>0 and nums[i]==nums[i-1] and not used[i-1]:
continue
path.append(nums[i])
used[i]=True
self.backtracking(nums,i+1,used,path,result)
used[i]=False
path.pop()