93.复原IP地址
题目描述: 93.复原IP地址.
解法
回溯
class Solution(object):
def is_vaild(self,start,end,path):
len_num = end - start
last_num = self.length - end
last_floor = 4-len(path)-1
if last_num>0 and last_floor >0 and last_num/last_floor > 3:
return False
if last_num > 0 and last_floor <=0:
return False
if last_floor > 0 and last_num <=0:
return False
if len_num > 1 and self.s[start] == '0':
return False
if int(self.s[start:end]) >255:
return False
return True
def backtrack(self,start,path):
if start == self.length and len(path) == 4:
self.res.append('.'.join(path))
return
for i in range(start+1,min(start+4,self.length+1)):
if self.is_vaild(start,i,path):
path.append(self.s[start:i])
self.backtrack(i,path)
path.pop()
def restoreIpAddresses(self, s):
self.s = s
self.length = len(s)
self.res = []
self.backtrack(0,[])
return self.res
本质上还是字符串的分割,但是多了一些限制条件,这些限制条件可以在进入回溯之前continue或者进入回溯之后return来完成
主要是以下限制条件,这些限制条件也完成了对回溯的剪枝:
1.每一个子串的位数如果大于1,那么第一位不可以是0
2.每一个子串的位数不大于3
3.如果当前子串取完数字,已经达到了4位ip地址,而还有剩下的子串,直接return
4.如果当前已经没有剩下的子串,但是还不够4位ip,直接return
5.如果剩下子串的长度除以还需要填补的位置大于3,则直接return
筛去以上条件,最后返回时可以直接用无剩余子串并且path长度为4为条件,将path用.进行连接,加入到res中
78.子集
题目描述: 78.子集.
解法
回溯
class Solution(object):
def backtrack(self,start,path):
self.res.append(path[:])
for i in range(start,self.length):
path.append(self.nums[i])
self.backtrack(i+1,path)
path.pop()
def subsets(self, nums):
self.nums = nums
self.length = len(nums)
self.res = []
self.backtrack(0,[])
return self.res
子集也是求组合的方式,只不过每次回溯的时候都要将当前的path加入到res中,注意传递给下层回溯的start应该是当前的i+1,这样可以避免重复遍历。
90.子集II
题目描述: 90.子集II.
解法
回溯
class Solution(object):
def backtrack(self,start,path):
self.res.append(path[:])
for i in range(start,self.length):
if i > start and self.nums[i] == self.nums[i-1]:
continue
path.append(self.nums[i])
self.backtrack(i+1,path)
path.pop()
def subsetsWithDup(self, nums):
self.nums = nums
self.nums.sort()
self.length = len(nums)
self.res = []
self.backtrack(0,[])
return self.res
由于遍历的数组中会出现重复的元素,所以最后遍历的结果也有可能发生重复的现象,为了避免重复,还是先将数组排序然后避免重复遍历,一定要记住每次遍历的i一定要先大于起点,然后再判断是不是和上一个重合。