文章目录
- [LeetCode:93. 复原IP地址](#LeetCode:93. 复原IP地址)
- [LeetCode:78. 子集](#LeetCode:78. 子集)
- [LeetCode:90. 子集 II](#LeetCode:90. 子集 II)
LeetCode:93. 复原IP地址
https://leetcode.cn/problems/palindrome-partitioning/description/
思路
- 从当前起始位置开始,分别截取长度为1、2、3的子串。
- 检查该子串是否是一个合法的 IP 段。
- 如果合法,则将其加入
path,并递归处理剩下的字符串和剩下的段数。 - 当已经得到四个段并且正好用完了整个字符串时,就找到了一个有效 IP 地址,将其加入结果。
解答
python
class Solution:
def restoreIpAddresses(self, s: str) -> List[str]:
results = []
path = []
n = len(s)
if n < 4 or n > 12: # 长度不符合,必然无法组成IP
return results
def backtrack(start: int, remain: int): # remain表示剩余几段
if n - start < remain or n - start > 3 * remain: # 剩余长度不符合要求
return
if remain == 0 and start == n: # 已分割四段、且字符用完
results.append(".".join(path))
return
for length in range(1, 4): # 分别截取长度为1, 2, 3的子串
if start + length > n:
break
sub_s = s[start:start+length]
if length > 1 and sub_s[0] == '0': # 前导零
continue
if int(sub_s) > 255: # 超过范围
continue
path.append(sub_s)
backtrack(start + length, remain - 1)
path.pop()
backtrack(0, 4)
return results
LeetCode:78. 子集
https://leetcode.cn/problems/subsets/
解答
python
class Solution:
def subsets(self, nums: List[int]) -> List[List[int]]:
n = len(nums)
results = []
path = []
def backtrack(start: int):
results.append(path[:])
for end in range(start, n):
path.append(nums[end])
backtrack(end + 1)
path.pop()
backtrack(0)
return results
LeetCode:90. 子集 II
https://leetcode.cn/problems/subsets-ii/description/
思路
首先对数组进行排序,后续同一层的递归中,如果遇到元素相同则跳过。
解答
python
class Solution:
def subsetsWithDup(self, nums: List[int]) -> List[List[int]]:
nums.sort() # 排序,方便后续去重
n = len(nums)
results = []
path = []
def backtrack(start):
results.append(path[:])
for i in range(start, n):
if i > start and nums[i] == nums[i-1]: # 同一层递归中,如果当前元素与前一个相同,跳过
continue
path.append(nums[i])
backtrack(i + 1)
path.pop()
backtrack(0)
return results