diff --git a/problems/0093.复原IP地址.md b/problems/0093.复原IP地址.md index 4e56ddc4..1d8ad296 100644 --- a/problems/0093.复原IP地址.md +++ b/problems/0093.复原IP地址.md @@ -342,32 +342,47 @@ class Solution: ``` python3: -```python -class Solution(object): - def restoreIpAddresses(self, s): - """ - :type s: str - :rtype: List[str] - """ - ans = [] - path = [] - def backtrack(path, startIndex): - if len(path) == 4: - if startIndex == len(s): - ans.append(".".join(path[:])) - return - for i in range(startIndex+1, min(startIndex+4, len(s)+1)): # 剪枝 - string = s[startIndex:i] - if not 0 <= int(string) <= 255: - continue - if not string == "0" and not string.lstrip('0') == string: - continue - path.append(string) - backtrack(path, i) - path.pop() +```python3 +class Solution: + def __init__(self): + self.result = [] - backtrack([], 0) - return ans``` + def restoreIpAddresses(self, s: str) -> List[str]: + ''' + 本质切割问题使用回溯搜索法,本题只能切割三次,所以纵向递归总共四层 + 因为不能重复分割,所以需要start_index来记录下一层递归分割的起始位置 + 添加变量point_num来记录逗号的数量[0,3] + ''' + self.result.clear() + if len(s) > 12: return [] + self.backtracking(s, 0, 0) + return self.result + + def backtracking(self, s: str, start_index: int, point_num: int) -> None: + # Base Case + if point_num == 3: + if self.is_valid(s, start_index, len(s)-1): + self.result.append(s[:]) + return + # 单层递归逻辑 + for i in range(start_index, len(s)): + # [start_index, i]就是被截取的子串 + if self.is_valid(s, start_index, i): + s = s[:i+1] + '.' + s[i+1:] + self.backtracking(s, i+2, point_num+1) # 在填入.后,下一子串起始后移2位 + s = s[:i+1] + s[i+2:] # 回溯 + else: + # 若当前被截取的子串大于255或者大于三位数,直接结束本层循环 + break + + def is_valid(self, s: str, start: int, end: int) -> bool: + if start > end: return False + # 若数字是0开头,不合法 + if s[start] == '0' and start != end: + return False + if not 0 <= int(s[start:end+1]) <= 255: + return False + return True ```