代码随想录算法训练营第二十四天| leetcode93.复原IP地址、 leetcode78.子集、leetcode90.子集II
1 leetcode93.复原IP地址
题目链接:93. 复原 IP 地址 - 力扣(LeetCode)
文章链接:代码随想录
视频链接:回溯算法如何分割字符串并判断是合法IP?| LeetCode:93.复原IP地址_哔哩哔哩_bilibili
思路:就是将这个字符串符合要求的进行一个收集,然后使用列表存储,最后使用join
函数将这个列表进行连接就好了
1.1自己的代码
才开始犯了个错误,就是终止条件判断的时候忘记整个字符串的长度不能超过四这个条件了
class Solution:
def __init__(self):
self.result = []
self.path = []
def restoreIpAddresses(self, s: str) -> List[str]:
self.backtracking(s,0)
return self.result
def backtracking(self,s,startindex):
if startindex==len(s) and len(self.path[:]) == 4:
path = '.'.join(self.path[:])
self.result.append(path)
return self.result
for i in range(startindex,len(s)):
if self.vaild_num(s[startindex:i+1]):
self.path.append(s[startindex:i+1])
self.backtracking(s,i+1)
self.path.pop()
def vaild_num(self,s):
if s.isdigit():
if 0<=int(s)<=255 and ((len(s)>1 and s[0] !='0')or(len(s)==1)):
return True
return False
1.2 视频后的思路
感觉视频里的思路对于python而言,没有我自己写的明了,感觉在判断当前的地址合法时有点啰嗦,嗯,更倾向于自己的这种方法
重点:发现这种方法耗时会很短的
class Solution:
def restoreIpAddresses(self, s: str) -> List[str]:
result = []
self.backtracking(s,0,0,'',result)
return result
def backtracking(self, s, start_index, point_num, current, result):
if point_num == 3:
if self.is_valid(s, start_index, len(s) - 1):
current += s[start_index:]
result.append(current)
return
for i in range(start_index, len(s)):
if self.is_valid(s, start_index, i):
sub = s[start_index:i + 1]
self.backtracking(s, i + 1, point_num + 1, current + 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
1.3 本题小结
- 其实这道题感觉理解了上个题目的思路以后,并不难,能自己写出来
- 我发现虽然在理解上视频的方法会难一点,但是代码的运行速度上面,这种方法确实很快
2 leetcode78.子集
文章链接:代码随想录
视频链接:回溯算法解决子集问题,树上节点都是目标集和! | LeetCode:78.子集_哔哩哔哩_bilibili
思路:嗯,想用之前的方法去尝试,发现好像不太行,还是看视频吧
2.1 视频后的代码
重点:我发现我不知道怎么写的地方居然是如何收获结果的,看了视频觉得自己有点不太聪明的样子
class Solution:
def __init__(self):
self.result = []
self.num = []
def subsets(self, nums: List[int]) -> List[List[int]]:
self.backtracking(nums,0)
return self.result
def backtracking(self,nums,startindex):
self.result.append(self.num[:])
if startindex ==len(nums):
return
for i in range(startindex,len(nums)):
self.num.append(nums[i])
self.backtracking(nums,i+1)
self.num.pop()
2.2 本题小结
- 这道题我不知道的是如何收获结果集,但是吧看了视频后又觉得自己不是很聪明的样子
- 真的好基础好模板化的一道题目
3 leetcode90.子集II
文章链接:代码随想录
视频链接:回溯算法解决子集问题,如何去重?| LeetCode:90.子集II_哔哩哔哩_bilibili
思路:看到这道题目,第一反应用之前组合的有一种去重可能就解决了,我先试试
3.1 自己的代码
真的和之前的思路没有任何区别
小问题:第一次提交忘记排序了
class Solution:
def __init__(self):
self.result = []
self.num = []
def subsetsWithDup(self, nums: List[int]) -> List[List[int]]:
nums.sort()
self.backtracking(nums,0)
return self.result
def backtracking(self,nums,startindex):
self.result.append(self.num[:])
if startindex==len(nums):
return
for i in range(startindex,len(nums)):
if i >startindex and nums[i]==nums[i-1]:
continue
self.num.append(nums[i])
self.backtracking(nums,i+1)
self.num.pop()
3.2 视频中的方法
使用used的方法,目前掌握的还不是很牢固,但是也还能写吧
class Solution:
def __init__(self):
self.result = []
self.num = []
def subsetsWithDup(self, nums: List[int]) -> List[List[int]]:
nums.sort()
used = [False]*len(nums)
self.backtracking(nums,0,used)
return self.result
def backtracking(self,nums,startindex,used):
self.result.append(self.num[:])
if startindex==len(nums):
return
for i in range(startindex,len(nums)):
if i >0 and nums[i]==nums[i-1] and not used[i-1]:
continue
self.num.append(nums[i])
used[i] = True
self.backtracking(nums,i+1,used)
used[i] = False
self.num.pop()
3.3 本题小结
- 这道题目真的没有难题,就是之前内容的一个结合,我目前只掌握了一种方法,使用used的方法会用,但是写的不是很好
- 这个题目没有什么难点,做会了前面的题目以后
4 今日小结
- 整体题目上没有什么特别新的点,就是在子集的时候我开始不知道如何收集结果
- 整体而言,都是比较容易可以上手,可以顺利写完的,第一次花很短的时间看完视频写完题目