LeetCode 209. 長度最小的子陣列
子陣列是一個連續的,很容易想到滑動視窗
class Solution:
def minSubArrayLen(self, target: int, nums: List[int]) -> int:
windowSum = 0
left, right = 0, 0
res = float('inf')
while right < len(nums):
push = nums[right]
windowSum += push
right += 1
while windowSum >= target:
res = min(res, right - left)
pop = nums[left]
windowSum -= pop
left += 1
return res if res != float('inf') else 0
擴充
如果 nums 陣列中包含負數,則視窗擴大時元素和不見得就增大,視窗縮小時元素和不見得就減小,這種情況就不能單純使用滑動視窗技巧了,可能需要混合動態規劃和單調佇列來做。
862. 和至少為 K 的最短子陣列
LeetCode 1425. 帶限制的子序列和
LeetCode 53. 最大子陣列和
這裡給出的是滑動視窗解法
class Solution:
def maxSubArray(self, nums: List[int]) -> int:
windowSum = 0
res = float("-inf")
left = right = 0
while right < len(nums):
push = nums[right]
windowSum += push
right += 1
res = max(res, windowSum)
while windowSum < 0:
pop = nums[left]
windowSum -= pop
left += 1
return res
LeetCode 59. 螺旋矩陣 II
模擬題,做這一題之前可以先試試 LeetCode 54. 螺旋矩陣
class Solution:
def generateMatrix(self, n: int) -> List[List[int]]:
matrix = [[None for _ in range(n)] for _ in range(n)]
idx = 1
a, b, x, y = 0, 0, n - 1, n - 1
for _ in range(n ** 2):
for j in range(b, y + 1):
matrix[a][j] = idx
idx += 1
a += 1
for i in range(a, x + 1):
matrix[i][y] = idx
idx += 1
y -= 1
for j in range(y, b - 1, -1):
matrix[x][j] = idx
idx += 1
x -= 1
for i in range(x, a - 1, -1):
matrix[i][b] = idx
idx += 1
b += 1
return matrix
LeetCode 54. 螺旋矩陣
class Solution:
def spiralOrder(self, matrix: List[List[int]]) -> List[int]:
m, n = len(matrix) - 1, len(matrix[0]) - 1
x, y = 0, 0
res = []
while x <= m and y <= n:
for j in range(y, n + 1):
if x <= m and y <= n:
res.append(matrix[x][j])
x += 1
for i in range(x, m + 1):
if x <= m and y <= n:
res.append(matrix[i][n])
n -= 1
for j in range(n, y - 1, -1):
if x <= m and y <= n:
res.append(matrix[m][j])
m -= 1
for i in range(m, x - 1, -1):
if x <= m and y <= n:
res.append(matrix[i][y])
y += 1
return res
KamaCoder 44. 開發商購買土地
字首和思想
import sys
def find(matrix):
m, n = len(matrix), len(matrix[0])
preSum_matrix = [[None for _ in range(n)] for _ in range(m)]
preSum_matrix[0][0] = matrix[0][0]
for i in range(m):
for j in range(n):
up = preSum_matrix[i - 1][j] if i - 1 >= 0 else 0
left = preSum_matrix[i][j - 1] if j - 1 >= 0 else 0
left_up = preSum_matrix[i - 1][j - 1] if i - 1 >= 0 and j - 1 >= 0 else 0
preSum_matrix[i][j] = matrix[i][j] + up + left - left_up
res = float('inf')
for i in range(m - 1):
if res == 0:
return 0
res = min(res, abs(preSum_matrix[m - 1][n - 1] - preSum_matrix[i][n - 1] * 2))
for j in range(n - 1):
if res == 0:
return 0
res = min(res, abs(preSum_matrix[m - 1][n - 1] - preSum_matrix[m - 1][j] * 2))
return res
if __name__ == "__main__":
lines = sys.stdin.read().strip().splitlines()
idx = 0
res = []
while idx < len(lines):
m, n = map(int, lines[idx].strip().split())
idx += 1
matrix = []
for _ in range(m):
line = list(map(int, lines[idx].strip().split()))
matrix.append(line)
idx += 1
res.append(str(find(matrix)))
sys.stdout.write("\n".join(res))
LeetCode 304. 二維區域和檢索 - 矩陣不可變
這一題同樣也是矩陣字首和思想
class NumMatrix:
def __init__(self, matrix: List[List[int]]):
m, n = len(matrix), len(matrix[0])
self.preSum_matrix = [[None for _ in range(n)] for _ in range(m)]
self.preSum_matrix[0][0] = matrix[0][0]
for i in range(m):
for j in range(n):
up = self.preSum_matrix[i - 1][j] if i - 1 >= 0 else 0
left = self.preSum_matrix[i][j - 1] if j - 1 >= 0 else 0
left_up = self.preSum_matrix[i - 1][j - 1] if i - 1 >= 0 and j - 1 >= 0 else 0
self.preSum_matrix[i][j] = matrix[i][j] + up + left - left_up
def sumRegion(self, row1: int, col1: int, row2: int, col2: int) -> int:
up = self.preSum_matrix[row1 - 1][col2] if row1 - 1 >= 0 else 0
left = self.preSum_matrix[row2][col1 - 1] if col1 - 1 >= 0 else 0
left_up = self.preSum_matrix[row1 - 1][col1 - 1] if row1 - 1 >= 0 and col1 - 1 >= 0 else 0
res = self.preSum_matrix[row2][col2] - up - left + left_up
return res
# Your NumMatrix object will be instantiated and called as such:
# obj = NumMatrix(matrix)
# param_1 = obj.sumRegion(row1,col1,row2,col2)