前言
继续leetcode刷题生涯
这里记录的都是笔者觉得有点意思的做法
参考了好几位大佬的题解,感谢各位大佬
1031. 两个非重叠子数组的最大和
class Solution:
def maxSumTwoNoOverlap(self, A: List[int], L: int, M: int) -> int:
n = len(A)
if L + M == n: return sum(A)
res = 0
presum = [0] * (n + 1)
for i in range(n):
presum[i + 1] = presum[i] + A[i]
premax = presum[-1] - presum[-M - 1]
for i in range(n - M - L, -1, -1):
premax = max(premax, presum[i + L + M] - presum[i + L])
res = max(res, presum[i + L] - presum[i] + premax)
premax = presum[-1] - presum[-L - 1]
for i in range(n - M - L, -1, -1):
premax = max(premax, presum[i + L + M] - presum[i + M])
res = max(res, presum[i + M] - presum[i] + premax)
return res
1032. 字符流
class Trie:
def __init__(self):
"""
Initialize your data structure here.
"""
self.Trie = {
}
def insert(self, word):
"""
Inserts a word into the trie.
:type word: str
:rtype: void
"""
curr = self.Trie
for w in word:
if w not in curr:
curr[w] = {
}
curr = curr[w]
curr['#'] = 1
def search(self, word):
"""
Returns if the word is in the trie.
:type word: str
:rtype: bool
"""
curr = self.Trie
for w in word:
if w not in curr:
return False
if "#" in curr[w]:
return True
curr = curr[w]
return False
class StreamChecker:
def __init__(self, words: List[str]):
self.trie = Trie()
self.stream = deque([])
for word in set(words):
self.trie.insert(word[::-1])
def query(self, letter: str) -> bool:
self.stream.appendleft(letter)
return self.trie.search(self.stream)
1033. 移动石子直到连续
class Solution:
def numMovesStones(self, a: int, b: int, c: int) -> List[int]:
x, y, z = sorted([a, b, c])
l = y - x - 1
r = z - y - 1
s = l + r
if s == 0:
return [0, s]
elif l == 0 or r == 0 or l == 1 or r == 1:
return [1, s]
else:
return [2, s]
1034. 边框着色
class Solution:
def colorBorder(self, grid: List[List[int]], r0: int, c0: int, color: int) -> List[List[int]]:
visited = set()
def dfs(i, j, color):
visited.add((i, j))
flag = True
for x, y in [[i - 1, j], [i + 1, j], [i, j - 1], [i, j + 1]]:
if 0 <= x < len(grid) and 0 <= y < len(grid[0]) and (x, y) not in visited:
if grid[x][y] == grid[i][j] :
dfs(x, y, color)
else:
flag = False
if i == 0 or i == len(grid) - 1 or j == 0 or j == len(grid[0]) - 1 or not flag:
grid[i][j] = color
dfs(r0, c0, color)
return grid
1035. 不相交的线
class Solution:
def maxUncrossedLines(self, A: List[int], B: List[int]) -> int:
m, n = len(A), len(B)
res = 0
dp = [[0 for _ in range(n + 1)] for _ in range(m + 1)]
for i in range(1, m + 1):
for j in range(1, n + 1):
if A[i - 1] == B[j - 1]:
dp[i][j] = dp[i - 1][j - 1] + 1
res = max(res, dp[i][j])
else:
dp[i][j] = max(dp[i - 1][j], dp[i][j - 1])
return res
1036. 逃离大迷宫
class Solution:
def isEscapePossible(self, blocked: List[List[int]], source: List[int], target: List[int]) -> bool:
n = len(blocked)
if n == 0: return True
block = set((i, j) for i, j in blocked)
max_steps = n * (n - 1) // 2
def dfs(i, j, steps, target_i, target_j, visited):
if steps > max_steps:
return True
if i < 0 or j < 0:
return False
if (i, j) in block:
return False
if i == target_i and j == target_j:
return True
visited.add((i, j))
for new_i, new_j in [(i+1, j), (i-1, j), (i, j-1), (i, j+1)]:
if (new_i, new_j) in visited:
continue
if dfs(new_i, new_j, steps+1, target_i, target_j, visited):
return True
return False
return dfs(source[0], source[1], 0, target[0], target[1], set()) and dfs(target[0], target[1], 0, source[0], source[1], set())
1037. 有效的回旋镖
class Solution:
def isBoomerang(self, points: List[List[int]]) -> bool:
(x1,y1),(x2,y2),(x3,y3) = points
return (x1*y2+x2*y3+x3*y1-y1*x2-y2*x3-y3*x1) != 0
1038. 把二叉搜索树转换为累加树
class Solution:
def bstToGst(self, root: TreeNode) -> TreeNode:
cur = 0
def dfs(root):
nonlocal cur
if not root: return
dfs(root.right)
cur += root.val
root.val = cur
dfs(root.left)
dfs(root)
return root
1039. 多边形三角剖分的最低得分
from functools import lru_cache
class Solution:
def minScoreTriangulation(self, A: List[int]) -> int:
@lru_cache(None)
def dfs(left, right):
if left + 1 == right: return 0
res = float('inf')
for k in range(left + 1, right):
res = min(res, dfs(left, k) + dfs(k, right) + A[left] * A[k] * A[right])
return res
return dfs(0, len(A) - 1)
1040. 移动石子直到连续 II
class Solution:
def numMovesStonesII(self, stones: List[int]) -> List[int]:
stones.sort()
n = len(stones)
max_moves = stones[n-1] - stones[0] + 1 - n - min(stones[n-1] - stones[n-2] - 1, stones[1] - stones[0] - 1)
min_moves=float('inf')
tmp = 0
for i in range(n):
while stones[i] - stones[tmp] + 1 > n:
tmp += 1
cost = n - (i - tmp + 1)
if cost == 1 and stones[i] - stones[tmp] + 1 == n - 1:
min_moves = min(min_moves, 2)
else:
min_moves = min(min_moves, cost)
return [min_moves, max_moves]