今日题目
93.复原IP地址
题目链接:93. 复原 IP 地址 - 力扣(LeetCode)
思考:本题需要在给出的字符串中分割三次,每次采用"."进行分割,分割后的四个部分,每一部分都要满足:(1)是不以0开头的整数;(2)范围在0-255之间。
分割次数达到3次作为终止条件,对于每一段分割的字符内容,都需要判断合法性。只有当前一段合法后,才会递归到下一段。
代码:
class Solution:
def restoreIpAddresses(self, s: str) -> List[str]:
result = []
self.dfs(s, 0, 0, "", result)
return result
def dfs(self, s, start, p_num, cur, result):
if p_num == 3:
if self.is_valid(s, start, len(s)-1):
cur += s[start:]
result.append(cur)
return
for i in range(start, len(s)):
if self.is_valid(s, start, i):
sub = s[start:i+1]
self.dfs(s, i+1, p_num+1, cur+sub+'.', result)
else:
break
def is_valid(self, s, start, end):
if start > end:
return False
if s[start] == '0' and start != end:
return False
num = 0
for i in range(start, end+1):
if not s[i].isdigit():
return False
num = num * 10 + int(s[i])
if num > 255:
return False
return True
78.子集
思考:本题需要遍历树结构,记录所有节点的情况,且节点不能重复。当遍历完数组所有元素后终止。一种情况是,每次递归,一个节点也不选,当遍历完数组所有元素后path为[]直接返回,符合题意[]也是一个子集。
另一种情况就是递归+回溯遍历所有节点。
代码:
class Solution:
def subsets(self, nums: List[int]) -> List[List[int]]:
ans = []
path = []
n = len(nums)
def dfs(i):
if i == n:
ans.append(path.copy())
return
dfs(i+1)
path.append(nums[i])
dfs(i+1)
path.pop()
dfs(0)
return ans
90.子集II
思考:上一题中数组元素不存在重复,本题存在重复元素。为了达到去重目的,首先对数组排序,这样在后续递归遍历中,遇到重复元素可以跳过,其余按照递归+回溯思想处理。
代码:
class Solution:
def subsetsWithDup(self, nums: List[int]) -> List[List[int]]:
ans = []
path = []
nums.sort()
def dfs(nums, start, path, ans):
ans.append(path[:])
for i in range(start, len(nums)):
if i > start and nums[i] == nums[i-1]:
continue
path.append(nums[i])
dfs(nums, i+1, path, ans)
path.pop()
dfs(nums, 0, path, ans)
return ans