代码随想录27期|Python|Day28|93.复原IP地址|78.子集|90.子集II

93. 复原 IP 地址

本题的思路和昨天的分割回文串一样,都是在回溯之前先判断。

不同点是:

1、终止条件多了一个path节点数==4的判定;

2、判断是否合法不仅是数值比较,还需要判断是否有前置的0。

class Solution(object):
    def restoreIpAddresses(self, s):
        """
        :type s: str
        :rtype: List[str]
        """
        res = []
        self.backtracking(0, [], res, s)
        return res
    
    def backtracking(self, start_idx, path, res, s):
        # 终止条件除了到达末尾以外,还需要路径中保存的节点数是4
        if start_idx == len(s) and len(path) == 4:
            res.append(".".join(path))
            return

        for i in range(start_idx, len(s)):
            # 这里和分割回文数写法一致
            if self.is_valid(start_idx, i, s):
                path.append(s[start_idx:i+1])
                self.backtracking(i+1, path, res, s)
                path.pop()
    
    def is_valid(self, start_idx, cur, s):
        # 开头是0,后面还有数字为不合法
        if s[start_idx] == '0' and cur != start_idx:
            return False
        cur_value = int(s[start_idx: cur+1])
        if cur_value > 255:  # 大于255不合法
            return False
        return True

78. 子集

本题需要保存全部的不重复节点,所以我们不是在遍历到叶子节点的时候再进行res的操作,而是需要在每一次回溯的时候进行res的保存。

class Solution(object):
    def subsets(self, nums):
        """
        :type nums: List[int]
        :rtype: List[List[int]]
        """
        res = []
        self.backtracking(0, res, [], nums)
        res.append([])
        return res

    def backtracking(self, start_idx, res, path, nums):
        if start_idx == len(nums):
            return

        for i in range(start_idx, len(nums)):
            path.append(nums[i])
            self.backtracking(i+1, res, path, nums)
            # 每次回溯到上一个节点的时候加入当前的路径
            res.append(path[:])
            path.pop()

90. 子集 II

本题是78.子集和40.组合II的杂交题,既要判断去重逻辑,又要保存所有的根节点和叶子节点。 

class Solution(object):
    def subsetsWithDup(self, nums):
        """
        :type nums: List[int]
        :rtype: List[List[int]]
        """
        res = []
        # 去重之前先排序,把相同的都放到一起
        nums.sort()
        self.backtracking(0, nums, [], res)
        res.append([])
        return res

    def backtracking(self, start_idx, nums, path, res):
        if start_idx == len(nums):
            return
        # 和之前的去重逻辑一样,如果当前和之前一致,说明已经被遍历,不需要在找了
        for i in range(start_idx, len(nums)):
            if i > start_idx and nums[i] == nums[i -1]:
                continue
            path.append(nums[i])
            self.backtracking(i+1, nums, path, res)
            # 和上一题的组合一样,需要保存路径上的所有节点
            res.append(path[:])
            path.pop()

今天的好简单,全是模版题!!!回溯法第一天的模版真的很重要!!!!

第28天完结(终于追上进度了

你可能感兴趣的:(python,开发语言)