代码随想录算法训练营第二十四天|93.复原IP地址、78.子集、90.子集II

今日题目

93.复原IP地址

题目链接:93. 复原 IP 地址 - 力扣(LeetCode)

思考:本题需要在给出的字符串中分割三次,每次采用"."进行分割,分割后的四个部分,每一部分都要满足:(1)是不以0开头的整数;(2)范围在0-255之间。

分割次数达到3次作为终止条件,对于每一段分割的字符内容,都需要判断合法性。只有当前一段合法后,才会递归到下一段。

代码:

class Solution:
    def restoreIpAddresses(self, s: str) -> List[str]:
        result = []
        self.dfs(s, 0, 0, "", result)
        return result

    def dfs(self, s, start, p_num, cur, result):
        if p_num == 3:
            if self.is_valid(s, start, len(s)-1):
                cur += s[start:]
                result.append(cur)
            return 
            
        for i in range(start, len(s)):
            if self.is_valid(s, start, i):
                sub = s[start:i+1]
                self.dfs(s, i+1, p_num+1, cur+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
78.子集

题目链接:78. 子集 - 力扣(LeetCode)

思考:本题需要遍历树结构,记录所有节点的情况,且节点不能重复。当遍历完数组所有元素后终止。一种情况是,每次递归,一个节点也不选,当遍历完数组所有元素后path为[]直接返回,符合题意[]也是一个子集。

另一种情况就是递归+回溯遍历所有节点。

代码:

class Solution:
    def subsets(self, nums: List[int]) -> List[List[int]]:
        ans = []
        path = []
        n = len(nums)
        def dfs(i):
            if i == n:
                ans.append(path.copy())
                return
            dfs(i+1)
            path.append(nums[i])
            dfs(i+1)
            path.pop()
        dfs(0)
        return ans
90.子集II

题目链接:90. 子集 II - 力扣(LeetCode)

思考:上一题中数组元素不存在重复,本题存在重复元素。为了达到去重目的,首先对数组排序,这样在后续递归遍历中,遇到重复元素可以跳过,其余按照递归+回溯思想处理。

代码:

class Solution:
    def subsetsWithDup(self, nums: List[int]) -> List[List[int]]:
        ans = []
        path = []
        nums.sort()

        def dfs(nums, start, path, ans):
            ans.append(path[:])
            for i in range(start, len(nums)):
                if i > start and nums[i] == nums[i-1]:
                    continue
                path.append(nums[i])
                dfs(nums, i+1, path, ans)
                path.pop()

        dfs(nums, 0, path, ans)
        return ans

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值