leetcode刷题记录91-100 python版

前言

继续leetcode刷题生涯
这里记录的都是笔者觉得有点意思的做法
参考了好几位大佬的题解,尤其是powcai大佬和labuladong大佬,感谢各位大佬

91. 解码方法

# 动态规划
class Solution:
    def numDecodings(self, s: str) -> int:
        dp = [0] * len(s)
        if s[0] == "0":
            return 0
        else:
            dp[0] = 1
        if len(s) == 1:
            return dp[-1]
        if s[1] != "0":
            dp[1] += 1
        if 10 <= int(s[:2]) <= 26:
            dp[1] += 1
        for i in range(2, len(s)):
            if s[i-1] + s[i] == "00":
                return 0
            if s[i] != "0":
                dp[i] += dp[i-1]
            if 10 <= int(s[i-1] + s[i]) <= 26:
                dp[i] += dp[i-2]
        return dp[-1]

92. 反转链表 II

class Solution:
    def reverseBetween(self, head: ListNode, m: int, n: int) -> ListNode:
            dummy = ListNode(-1)
            dummy.next = head
            p = dummy
            for _ in range(m-1):
                p = p.next
            node = None
            cur = p.next
            for _ in range(n-m+1):
                tmp = cur.next
                cur.next = node
                node = cur
                cur = tmp
            p.next.next = cur
            p.next = node
            return dummy.next

93. 复原IP地址

# 回溯
class Solution:
    def restoreIpAddresses(self, s: str) -> List[str]:
        res = []
        n = len(s)
        def backtrack(i, tmp, flag):
            if i == n and flag == 0:
                res.append(tmp[:-1])
                return
            if flag < 0:
                return
            for j in range(i, i+3):
                if j < n:
                    if i == j and s[j] == "0":
                        backtrack(j+1, tmp+s[j]+".", flag-1)
                        break
                    if 0 < int(s[i:j+1]) <= 255:
                        backtrack(j+1, tmp+s[i:j+1]+".", flag-1)
        backtrack(0, "", 4)
        return res
# 暴力
class Solution:
    def restoreIpAddresses(self, s: str) -> List[str]:
        n = len(s)
        res = []
      # 判读是否满足ip的条件
        def helper(tmp):
            if not tmp or (tmp[0] == "0" and len(tmp) > 1) or int(tmp) > 255:
                return False
            return True
      # 三个循环,把数字分成四份
        for i in range(3):
            for j in range(i + 1, i + 4):
                for k in range(j + 1, j + 4):
                    if i < n and j < n and k < n:
                        tmp1 = s[:i + 1]
                        tmp2 = s[i + 1:j + 1]
                        tmp3 = s[j + 1:k + 1]
                        tmp4 = s[k + 1:]
                        if all(map(helper, [tmp1, tmp2, tmp3, tmp4])):
                            res.append(tmp1 + "." + tmp2 + "." + tmp3 + "." + tmp4)
        return res

94. 二叉树的中序遍历

# 递归
class Solution:
    def inorderTraversal(self, root: TreeNode) -> List[int]:
        res = []
        def helper(root):
            if not root:
                return
            helper(root.left)
            res.append(root.val)
            helper(root.right)
        helper(root)
        return res
# 迭代
class Solution:
    def inorderTraversal(self, root: TreeNode) -> List[int]:
        res = []
        stack = []
        p = root
        while p or stack:
            while p:
                stack.append(p)
                p = p.left
            p = stack.pop()
            res.append(p.val)
            p = p.right
        return res

95. 不同的二叉搜索树 II

class Solution:
    def generateTrees(self, n: int) -> List[TreeNode]:
        if n == 0: return []
        def helper(start, end):
            res = []
            if start > end:
                res.append(None)
            for val in range(start, end + 1):
                for l in helper(start, val - 1):
                    for r in helper(val + 1, end):
                        root = TreeNode(val)
                        root.left = l
                        root.right = r
                        res.append(root)
            return res
        return helper(1, n)

96. 不同的二叉搜索树

class Solution:
    def numTrees(self, n: int) -> int:
        if n == 0: return 0
        def helper(start, end):
            res = []
            if start > end:
                res.append(None)
            for i in range(start, end + 1):
                for j in helper(start, i - 1):
                    for k in helper(i + 1, end):
                        root = TreeNode(i)
                        root.left = j
                        root.right = k
                        res.append(root)
            return res
        return len(helper(1, n))
# 动态规划
class Solution:
    def numTrees(self, n: int) -> int:
        dp = [0] * (n + 1)
        dp[0] = 1
        dp[1] = 1
        for i in range(2, n + 1):
            for j in range(i):
                dp[i] += dp[j] * dp[i - j - 1]
        return dp[-1]

97. 交错字符串

# 动态规划
class Solution:
    def isInterleave(self, s1: str, s2: str, s3: str) -> bool:
        n1, n2, n3 = len(s1), len(s2), len(s3)
        if n1 + n2 != n3: return False
        dp = [[False] * (n2 + 1) for _ in range(n1 +1)]
        dp[0][0] = True
        for j in range(1, n2 + 1):
            dp[0][j] = (dp[0][j-1] and s2[j-1] == s3[j-1])
        for i in range(1, n1 + 1):
            dp[i][0] = (dp[i-1][0] and s1[i-1] == s3[i-1])
        for i in range(1, n1+1):
            for j in range(1, n2+1):
                dp[i][j] = (dp[i-1][j] and s1[i-1] == s3[i+j-1]) or (dp[i][j-1] and s2[j-1] == s3[i+j-1])
        return dp[-1][-1]
# bfs
class Solution:
    def isInterleave(self, s1: str, s2: str, s3: str) -> bool:
        from collections import deque
        n1 = len(s1)
        n2 = len(s2)
        n3 = len(s3)
        if n1 + n2 != n3: return False
        queue = deque()
        queue.appendleft((0, 0))
        visited = set()
        while queue:
            i, j = queue.pop()
            if i == n1 and j == n2:
                return True
            if i < n1 and s1[i] == s3[i + j] and (i + 1, j) not in visited:
                visited.add((i + 1, j))
                queue.appendleft((i + 1, j))
            if j < n2 and s2[j] == s3[i + j] and (i, j + 1) not in visited:
                visited.add((i, j + 1))
                queue.appendleft((i, j + 1))
        return False

98. 验证二叉搜索树

class Solution:
    def isValidBST(self, root: TreeNode) -> bool:
        def isBST(root, min_val, max_val):
            if root == None: return True
            if root.val >= max_val or root.val <= min_val: return False
            return isBST(root.left, min_val, root.val) and isBST(root.right, root.val, max_val)
        return isBST(root, float("-inf"), float("inf"))
# 递归中序
class Solution:
    def isValidBST(self, root: TreeNode) -> bool:
        self.pre = None
        def isBST(root):
            if not root:
                return True
            if not isBST(root.left):
                return False
            if self.pre and self.pre.val >= root.val:
                return False
            self.pre = root
            return  isBST(root.right)
        return isBST(root)

99. 恢复二叉搜索树

# 迭代
class Solution:
    def recoverTree(self, root: TreeNode) -> None:
        """
        Do not return anything, modify root in-place instead.
        """
        firstNode, secondNode = None, None
        pre = TreeNode(float("-inf"))
        stack = []
        p = root
        while p or stack:
            while p:
                stack.append(p)
                p = p.left
            p = stack.pop()
            if not firstNode and pre.val > p.val:
                firstNode = pre
            if firstNode and pre.val >p.val:
                secondNode = p
            pre = p
            p = p.right
        firstNode.val, secondNode.val = secondNode.val, firstNode.val
# 递归
class Solution:
    def recoverTree(self, root: TreeNode) -> None:
        """
        Do not return anything, modify root in-place instead.
        """
        self.firstNode = None
        self.secondNode = None
        self.preNode = TreeNode(float("-inf"))
        def in_order(root):
            if not root:
                return
            in_order(root.left)
            if self.firstNode == None and self.preNode.val >= root.val:
                self.firstNode = self.preNode
            if self.firstNode and self.preNode.val >= root.val:
                self.secondNode = root
            self.preNode = root
            in_order(root.right)
        in_order(root)
        self.firstNode.val, self.secondNode.val = self.secondNode.val, self.firstNode.val

100. 相同的树

class Solution:
    def isSameTree(self, p: TreeNode, q: TreeNode) -> bool:
        if not p and not q: return True
        if p and q and p.val == q.val:
            return self.isSameTree(p.left, q.left) and self.isSameTree(p.right, q.right)
        return False

你可能感兴趣的:(leetcode)