继续leetcode刷题生涯
这里记录的都是笔者觉得有点意思的做法
参考了好几位大佬的题解,尤其是powcai大佬和labuladong大佬,感谢各位大佬
# 动态规划
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]
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
# 回溯
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
# 递归
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
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)
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]
# 动态规划
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
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)
# 迭代
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
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