【第三周打卡完成✔】
- 有一点点题感(遇到问题会去联想和过去遇到的问题相似之处)
- 做题速度已经能够达到一个小时4~5道题
- 但是有点为了进度囫囵吞枣【下周开始保持两道新题+复习】
- 发布一道题解!
#56.合并区间【排序】
class Solution:
def merge(self, intervals: List[List[int]]) -> List[List[int]]:
intervals.sort()
ans = [intervals[0]]
for s,e in intervals[1:]:
if ans[-1][1]<s:
ans.append([s,e])
else:
ans[-1][1] = max(ans[-1][1],e)
return ans
#62.不同路径【动态规划】
class Solution:
def uniquePaths(self, m: int, n: int) -> int:
dp = [[1]*n for _ in range(m)]
for i in range(1,m):
for j in range(1,n):
dp[i][j] = dp[i][j-1]+dp[i-1][j]
return dp[-1][-1]
#64.最小路径和【动态规划】
class Solution:
def minPathSum(self, grid: List[List[int]]) -> int:
for i in range(len(grid)):
for j in range(len(grid[0])):
if i==j==0:
continue
elif i==0:
grid[i][j] = grid[i][j-1] + grid[i][j]
elif j ==0:
grid[i][j] = grid[i-1][j] + grid[i][j]
else:
grid[i][j] = min(grid[i-1][j],grid[i][j-1])+grid[i][j]
return grid[-1][-1]
#70.爬楼梯【动态规划】
class Solution:
def climbStairs(self, n: int) -> int:
dp = [0]*(n+1)
dp[0] = dp[1] = 1
for i in range(2,n+1):
dp[i] = dp[i-1]+dp[i-2]
return dp[-1]
#72.编辑距离【动态规划】
class Solution:
def minDistance(self, word1: str, word2: str) -> int:
n1 = len(word1)
n2 = len(word2)
dp = [[0]*(n2+1) for _ in range(n1+1)]
for j in range(1,n2+1):
dp[0][j] = dp[0][j-1]+1
for i in range(1,n1+1):
dp[i][0] = dp[i-1][0]+1
for i in range(1,n1+1):
for j in range(1,n2+1):
if word1[i-1] == word2[j-1]:
dp[i][j] = dp[i-1][j-1]
else:
dp[i][j] = min(dp[i][j-1],dp[i-1][j],dp[i-1][j-1])+1
return dp[-1][-1]
#75.颜色分类【动态规划】
class Solution:
def sortColors(self, nums: List[int]) -> None:
p0,curr,p2 = 0,0,len(nums)-1
while curr <= p2:
if nums[curr] == 0:
nums[p0],nums[curr] = nums[curr],nums[p0]
p0 += 1
curr += 1
elif nums[curr] == 2:
nums[p2],nums[curr] = nums[curr],nums[p2]
p2 -= 1
else:
curr += 1
#78.子集【回溯】
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
#79.单词搜索【回溯】
class Solution:
def exist(self, board: List[List[str]], word: str) -> bool:
def dfs(i,j,k):
if not 0 <= i < len(board) or not 0 <= j < len(board[0]) or board[i][j] != word[k]:
return False
if k == len(word) -1:
return True
board[i][j] = ''
res = dfs(i+1,j,k+1) or dfs(i-1,j,k+1) or dfs(i,j+1,k+1) or dfs(i,j-1,k+1)
board[i][j] = word[k]
return res
for i in range(len(board)):
for j in range(len(board[0])):
if dfs(i,j,0):
return True
return False
#94.二叉树的中序遍历【二叉树】
class Solution:
def inorderTraversal(self, root: Optional[TreeNode]) -> List[int]:
WHITE,GRAY = 0,1
res = []
stack = [(WHITE,root)]
while stack:
color,node = stack.pop()
if node is None:continue
if color == WHITE:
stack.append((WHITE,node.right))
stack.append((GRAY,node))
stack.append((WHITE,node.left))
else:
res.append(node.val)
return res
#96.不同的二叉搜索树【二叉树】
class Solution:
def numTrees(self, n: int) -> int:
store = [1,1]
if n <= 1:
return store[n]
for m in range(2,n+1):
s = m-1
count = 0
for i in range(m):
count += store[i]*store[s-i]
store.append(count)
return store[n]
#98.验证二叉搜索树【二叉树】
class Solution:
def isValidBST(self, root: Optional[TreeNode]) -> bool:
WHITE,GRAY = 0,1
res = []
stack = [(WHITE,root)]
while stack:
color,root = stack.pop()
if root is None:continue
if color == WHITE:
stack.append((WHITE,root.right))
stack.append((GRAY,root))
stack.append((WHITE,root.left))
else:
res.append(root.val)
return res == sorted(res) and len(set(res)) == len(res)
#101.对称二叉树【递归】
class Solution:
def isSymmetric(self, root: Optional[TreeNode]) -> bool:
if not root:
return True
def bfs(root1,root2):
if not root1 and not root2:return True
if not root1 or not root2:return False
if root1.val != root2.val :return False
return bfs(root1.left,root2.right) and bfs(root1.right,root2.left)
return bfs(root.left,root.right)
#102.二叉树的层序遍历【广度优先搜索】
class Solution:
def levelOrder(self, root: Optional[TreeNode]) -> List[List[int]]:
if not root:return []
res,queue = [],collections.deque()
queue.append(root)
while queue:
tmp = []
for _ in range(len(queue)):
node = queue.popleft()
tmp.append(node.val)
if node.left:queue.append(node.left)
if node.right:queue.append(node.right)
res.append(tmp)
return res
#104.二叉树的最大深度【广度优先搜索】
class Solution:
def maxDepth(self, root: Optional[TreeNode]) -> int:
if not root:return 0
queue,res = [root],0
while queue:
tmp = []
for node in queue:
if node.left:tmp.append(node.left)
if node.right:tmp.append(node.right)
queue = tmp
res += 1
return res
#105.从前序与中序遍历序列构造二叉树【递归】
class Solution:
def buildTree(self, preorder: List[int], inorder: List[int]) -> Optional[TreeNode]:
if not preorder or not inorder:return
root = TreeNode(preorder[0])
idx = inorder.index(preorder[0])
root.left = self.buildTree(preorder[1:1+idx],inorder[:idx])
root.right = self.buildTree(preorder[1+idx:],inorder[1+idx:])
return root
#106.从中序与后序遍历序列构造二叉树【递归】
class Solution:
def buildTree(self, inorder: List[int], postorder: List[int]) -> Optional[TreeNode]:
if not inorder or not postorder:return
root = TreeNode(postorder[-1])
idx = inorder.index(postorder[-1])
root.left = self.buildTree(inorder[:idx],postorder[:idx])
root.right = self.buildTree(inorder[1+idx:],postorder[idx:-1])
return root
#114.二叉树展开为链表【递归】
class Solution:
def flatten(self, root: Optional[TreeNode]) -> None:
"""
Do not return anything, modify root in-place instead.
"""
if not root: return
node = root.left
if node:
while node.right:
node = node.right
node.right = root.right
root.right = root.left
root.left = None
self.flatten(root.right)
#121.买卖股票的最佳时机【前缀和】
class Solution:
def maxProfit(self, prices: List[int]) -> int:
ans,min_pre_sum = 0,inf
for v in prices:
ans = max(ans,v-min_pre_sum)
min_pre_sum = min(min_pre_sum,v)
return ans
#128.最长连续序列【哈希表】
class Solution:
def longestConsecutive(self, nums: List[int]) -> int:
res = 0
num_set = set(nums)
for num in num_set:
if (num - 1) not in num_set:
seq_len = 1
while (num + 1) in num_set:
seq_len += 1
num += 1
res = max(res,seq_len)
return res
#136.只出现一次的数字【⭐】
class Solution:
def singleNumber(self, nums: List[int]) -> int:
stack = []
for num in nums:
if num in stack:
stack.remove(num)
else:
stack.append(num)
return stack.pop()
#139.单词拆分【动态规划】
class Solution:
def wordBreak(self, s: str, wordDict: List[str]) -> bool:
n = len(s)
dp = [False]*(n+1)
dp[0] = True
for i in range(n):
for j in range(i+1,n+1):
if(dp[i] and (s[i:j] in wordDict)):
dp[j] = True
return dp[-1]
#141.环形链表【双指针】
class Solution:
def hasCycle(self, head: Optional[ListNode]) -> bool:
slow = fast = head
while fast and fast.next:
slow = slow.next
fast = fast.next.next
if fast is slow:
return True
return False