【第五周打卡完成✔】
- 一天不落的完成啦~
- 后50%的题目明显感觉由于没有深入思考和总结套路而力不从心
- 准备下周开始一轮复习并接入ACM模式的训练
#236.二叉树的最近公共祖先【二叉树】
class Solution:
def lowestCommonAncestor(self, root: 'TreeNode', p: 'TreeNode', q: 'TreeNode') -> 'TreeNode':
if not root or root == p or root == q:return root
left = self.lowestCommonAncestor(root.left,p,q)
right = self.lowestCommonAncestor(root.right,p,q)
if not left:return right
if not right:return left
return root
#238.除自身以外数组的乘积【数组】
class Solution:
def productExceptSelf(self, nums: List[int]) -> List[int]:
ans,tmp = [1]*len(nums),1
for i in range(1,len(nums)):
ans[i] = ans[i-1]*nums[i-1]
for i in range(len(nums)-2,-1,-1):
tmp *= nums[i+1]
ans[i] *= tmp
return ans
#240.搜索二维矩阵II【矩阵】
class Solution:
def searchMatrix(self, matrix: List[List[int]], target: int) -> bool:
i,j = len(matrix)-1,0
while i >= 0 and j <len(matrix[0]):
if matrix[i][j] > target:i -= 1
elif matrix[i][j] < target:j += 1
else:return True
return False
#279.完全平方数【动态规划】
class Solution:
def numSquares(self, n: int) -> int:
dp = [i for i in range(n+1)]
for i in range(2,n+1):
for j in range(1,int(i**(0.5))+1):
dp[i] = min(dp[i],dp[i-j*j]+1)
return dp[-1]
#283.移动零【双指针】
class Solution:
def moveZeroes(self, nums: List[int]) -> None:
j = 0
for i in range(len(nums)):
if nums[i]:
nums[i],nums[j] = nums[j],nums[i]
j += 1
#287.寻找重复数【快慢指针】
class Solution:
def findDuplicate(self, nums: List[int]) -> int:
slow,fast = 0,0
while True:
slow = nums[slow]
fast = nums[nums[fast]]
if fast == slow:
break
find = 0
while slow != find:
slow = nums[slow]
find = nums[find]
return find
#300.最长递增子序列【动态规划】
class Solution:
def lengthOfLIS(self, nums: List[int]) -> int:
if not nums:return 0
dp = [1]*len(nums)
for i in range(len(nums)):
for j in range(i):
if nums[j] < nums[i]:
dp[i] = max(dp[i],dp[j]+1)
return max(dp)
#309.买卖股票的最佳时机含冷冻期【动态规划】
class Solution:
def maxProfit(self, prices: List[int]) -> int:
n = len(prices)
dp = [[0,0] for _ in range(n)]
dp[0] = [-prices[0],0]
for i in range(1,n):
dp[i][0] = max(dp[i-1][0],-prices[i]+(dp[i-2][1] if i>1 else 0))
dp[i][1] = max(dp[i-1][1],+prices[i]+dp[i-1][0])
return dp[-1][-1]
#322.零钱兑换【动态规划】
class Solution:
def coinChange(self, coins: List[int], amount: int) -> int:
dp = [float('inf')]*(amount+1)
dp[0] = 0
for i in range(1,amount+1):
for j in range(len(coins)):
if coins[j] <= i:
dp[i] = min(dp[i],dp[i-coins[j]]+1)
return dp[amount] if dp[amount] != float('inf') else -1
#337.打家劫舍III【动态规划】
class Solution:
def rob(self, root: Optional[TreeNode]) -> int:
def _rob(root):
if not root:return 0,0
left = _rob(root.left)
right = _rob(root.right)
v1 = root.val + left[1] +right[1]
v2 = max(left)+max(right)
return v1,v2
return max(_rob(root))
#338.比特位计数【⭐】
class Solution:
def countBits(self, n: int) -> List[int]:
res = []
for i in range(n+1):
res.append(bin(i).count("1"))
return res
#347.前K个高频元素【⭐】
class Solution:
def topKFrequent(self, nums: List[int], k: int) -> List[int]:
count = collections.Counter(nums)
return [item[0] for item in count.most_common(k)]
#394.字符串解码【栈】
class Solution:
def decodeString(self, s: str) -> str:
stack,res,multi = [],"",0
for c in s:
if c == '[':
stack.append([multi,res])
res,multi = "",0
elif c == ']':
curr_multi,last_res = stack.pop()
res = last_res + curr_multi * res
elif '0' <= c <= '9':
multi = multi *10 + int(c)
else:
res += c
return res
#399.除法求值【图论】
class Solution:
def calcEquation(self, equations: List[List[str]], values: List[float], queries: List[List[str]]) -> List[float]:
graph = {}
for (x,y),v in zip(equations,values):
if x in graph:
graph[x][y] = v
else:
graph[x] = {y:v}
if y in graph:
graph[y][x] = 1/v
else:
graph[y] = {x:1/v}
def dfs(s,t) -> int:
if s not in graph:
return -1
if t == s:
return 1
for node in graph[s].keys():
if node == t:
return graph[s][node]
elif node not in visited:
visited.add(node)
v = dfs(node,t)
if v != -1:
return graph[s][node] * v
return -1
res = []
for qs,qt in queries:
visited = set()
res.append(dfs(qs,qt))
return res
#406.根据身高重建队列【排序】
class Solution:
def reconstructQueue(self, people: List[List[int]]) -> List[List[int]]:
res = []
people = sorted(people,key = lambda x:(-x[0],x[1]))
for p in people:
if len(res) <= p[1]:
res.append(p)
elif len(res) > p[1]:
res.insert(p[1],p)
return res
#416.分割等和子集【动态规划】
class Solution:
def canPartition(self, nums: List[int]) -> bool:
all_sum,N = sum(nums),len(nums)
if all_sum%2 == 1:
return False
half_sum = all_sum // 2
dp = [False] * (half_sum+1)
dp[0] = True
for i in range(len(nums)):
for j in range(half_sum,nums[i] - 1,-1):
dp[j] = dp[j] or dp[j -nums[i]]
return dp[-1]
#437.路径总和III【前缀和】
class Solution:
def pathSum(self, root: Optional[TreeNode], targetSum: int) -> int:
def dfs(node,cnts,cursum):
if not node:return 0
cursum += node.val
ans = cnts[cursum - targetSum]
cnts[cursum] += 1
if node.left:
ans += dfs(node.left,cnts,cursum)
if node.right:
ans += dfs(node.right,cnts,cursum)
cnts[cursum] -= 1
return ans
return dfs(root,Counter([0]),0)
#438.找到字符串中所有字母异位词【滑动窗口】
class Solution:
def findAnagrams(self, s: str, p: str) -> List[int]:
m,n = len(s),len(p)
ans = []
if m < n:
return ans
cnts_p = [0] * 26
for c in p:
cnts_p[ord(c) - ord('a')] += 1
cur = [0] * 26
for i in range(m):
cur[ord(s[i]) - ord('a')] += 1
if i >= n - 1:
if cur == cnts_p:
ans.append(i - n + 1)
cur[ord(s[i - n + 1]) -ord('a')] -= 1
return ans
#448.找到所有数组中消失的数字【⭐】
class Solution:
def findDisappearedNumbers(self, nums: List[int]) -> List[int]:
counter = set(nums)
N = len(nums)
res = []
for i in range(1,N+1):
if i not in counter:
res.append(i)
return res
#461.汉明距离【⭐】
class Solution:
def hammingDistance(self, x: int, y: int) -> int:
return bin(x ^ y).count('1')
#494.目标和【动态规划】
class Solution:
def findTargetSumWays(self, nums: List[int], target: int) -> int:
target += sum(nums)
if target < 0 or target % 2:
return 0
target //= 2
n = len(nums)
f = [[0] * (target + 1) for _ in range(n+1)]
f[0][0] = 1
for i,x in enumerate(nums):
for c in range(target + 1):
if c < x:
f[i+1][c] = f[i][c]
else:
f[i+1][c] = f[i][c]+f[i][c-x]
return f[n][target]
#538.把二叉搜索树转化为累加树【递归】
class Solution:
def convertBST(self, root: Optional[TreeNode]) -> Optional[TreeNode]:
s = 0
def dfs(node):
if node is None:
return
dfs(node.right)
nonlocal s
s += node.val
node.val = s
dfs(node.left)
dfs(root)
return root
#543.二叉树的直径【递归】
class Solution:
def diameterOfBinaryTree(self, root: Optional[TreeNode]) -> int:
self.ans = 1
def depth(root):
if not root:return 0
L = depth(root.left)
R = depth(root.right)
self.ans = max(self.ans,L+R+1)
return max(L,R) + 1
depth(root)
return self.ans - 1
#560.和为k的子数组【前缀和】
class Solution:
def subarraySum(self, nums: List[int], k: int) -> int:
num_times = collections.defaultdict(int)
num_times[0] = 1
cur_sum = 0
res = 0
for i in range(len(nums)):
cur_sum += nums[i]
if cur_sum - k in num_times:
res += num_times[cur_sum - k]
num_times[cur_sum] += 1
return res
#581.最短无序连续子数组【双指针】
class Solution:
def findUnsortedSubarray(self, nums: List[int]) -> int:
new_nums = sorted(nums)
left,right = 0,len(nums)-1
while left < len(nums):
if nums[left] != new_nums[left]:
break
left += 1
if left == len(nums):
return 0
while right > left:
if nums[right] != new_nums[right]:
break
right -= 1
return right - left + 1
#617.合并二叉树【递归】
class Solution:
def mergeTrees(self, root1: Optional[TreeNode], root2: Optional[TreeNode]) -> Optional[TreeNode]:
if root1 is None:return root2
if root2 is None:return root1
return TreeNode(root1.val + root2.val,
self.mergeTrees(root1.left,root2.left),
self.mergeTrees(root1.right,root2.right))
#621.任务调度器【贪心算法】
class Solution:
def leastInterval(self, tasks: List[str], n: int) -> int:
ct = collections.Counter(tasks)
nbucket = ct.most_common(1)[0][1]
last_bucket_size = list(ct.values()).count(nbucket)
res = (nbucket - 1)*(n+1)+last_bucket_size
return max(res,len(tasks))
#647.回文子串【动态规划】
class Solution:
def countSubstrings(self, s: str) -> int:
dp = [[False] * len(s) for _ in range(len(s))]
result = 0
for i in range(len(s)-1,-1,-1):
for j in range(i,len(s)):
if s[i] == s[j]:
if j - i <= 1:
result += 1
dp[i][j] = True
elif dp[i+1][j-1]:
result += 1
dp[i][j] = True
return result
#739.每日温度【单调栈】
class Solution:
def dailyTemperatures(self, temperatures: List[int]) -> List[int]:
n = len(temperatures)
ans = [0] * n
st = []
for i in range(n-1,-1,-1):
t = temperatures[i]
while st and t >= temperatures[st[-1]]:
st.pop()
if st:
ans[i] = st[-1] - i
st.append(i)
return ans