程式碼隨想錄演算法訓練營第24天 | 93.復原IP地址 78.子集 90.子集Ⅱ

Y荷兰豆Y發表於2024-06-29

93.復原IP地址

給定一個只包含數字的字串,復原它並返回所有可能的 IP 地址格式。
有效的 IP 地址 正好由四個整數(每個整數位於 0 到 255 之間組成,且不能含有前導 0),整數之間用 '.' 分隔。
例如:"0.1.2.201" 和 "192.168.1.1" 是 有效的 IP 地址,但是 "0.011.255.245"、"192.168.1.312" 和 "192.168@1.1" 是 無效的 IP 地址。

解題

1.遞迴引數:
startIndex一定是需要的,因為不能重複分割,記錄下一層遞迴分割的起始位置。
2.終止條件:
終止條件和131.分割回文串情況就不同了,本題明確要求只會分成4段,所以不能用切割線切到最後作為終止條件,而是分割的段數作為終止條件。
然後驗證一下第四段是否合法,如果合法就加入到結果集裡
3.單層搜尋的邏輯:
在for (int i = startIndex; i < s.size(); i++)迴圈中 [startIndex, i] 這個區間就是擷取的子串,需要判斷這個子串是否合法。

點選檢視程式碼
class Solution:
    def restoreIpAddresses(self, s: str) -> List[str]:
        result=[]
        self.backtracking(s,0,0,[],result)
        return result
    def backtracking(self,s,startIndex,pointNum,path,result):
        if pointNum==3:
            if self.is_valid(s,startIndex,len(s)-1):
                result.append('.'.join(path+[s[startIndex:]]))
                return
        for i in range(startIndex,len(s)):
            if self.is_valid(s,startIndex,i):
                sub=s[startIndex:i+1]
                path.append(sub)
                pointNum+=1
                self.backtracking(s,i+1,pointNum,path,result)
                pointNum-=1
                path.pop()
            else:
                break
    def is_valid(self,s,start,end):
        if start>end:
            return False
        if s[start]=='0' and start!=end:
            return False
        if 0<=int(s[start:end+1])<=255:
            return True

78.子集

給定一組不含重複元素的整數陣列 nums,返回該陣列所有可能的子集(冪集)。
說明:解集不能包含重複的子集。

解題

可以不需要加終止條件,因為startIndex >= nums.size(),本層for迴圈本來也結束了。
報錯:1.遞迴裡是i+1不是startIndex+1;2.新增結果時用path[:]淺複製新增path的當前狀態,不是直接用path

點選檢視程式碼
class Solution:
    def subsets(self, nums: List[int]) -> List[List[int]]:
        result=[]
        self.backtracking(nums,0,[],result)
        return result

    def backtracking(self,nums,startIndex,path,result):
        result.append(path[:])
        for i in range(startIndex,len(nums)):
            path.append(nums[i])
            self.backtracking(nums,i+1,path,result)
            path.pop()

90.子集Ⅱ

給定一個可能包含重複元素的整數陣列 nums,返回該陣列所有可能的子集(冪集)。
說明:解集不能包含重複的子集。

解題

利用used陣列進行樹層的去重,nums和i-1的元素相同並且i-1的used是False,背題就完事了!
題目和上一道差不多,去重思路和昨天的40也一樣。

點選檢視程式碼
class Solution:
    def subsetsWithDup(self, nums: List[int]) -> List[List[int]]:
        result=[]
        nums.sort()
        used=[False]*len(nums)
        self.backtracking(nums,0,used,[],result)
        return result
    def backtracking(self,nums,startIndex,used,path,result):
        result.append(path[:])
        for i in range(startIndex,len(nums)):
            if i>0 and nums[i]==nums[i-1] and not used[i-1]:
                continue
            path.append(nums[i])
            used[i]=True
            self.backtracking(nums,i+1,used,path,result)
            used[i]=False
            path.pop()

相關文章