题目
题目一:长度最小子数组
给定一个含有
n
个正整数的数组和一个正整数target
。 找出该数组中满足其总和大于等于target
的长度最小的子数组[numsl, numsl+1, ..., numsr-1, numsr]
,并返回其长度。如果不存在符合条件的子数组,返回 0。
整体思路:前缀和
- 预先维护一个前缀和数组
pre_sums
- 使用快慢指针思路,
slow
,fast
初始化为0,1 - 当
pre_sums[fast]-pre_sums[slow]
小于target
时,fast
指针不断右移 - 当
pre_sums[fast]-pre_sums[slow]
大于等于target
时,更新长度最小子数组的值 - 右移
slow
,直到pre_sums[fast]-pre_sums[slow]
小于target
为止,同时更新长度最小子数组的值 fast
右移至pre_sums
最右侧,且slow
右移完毕后,整个循环结束
class Solution:
def minSubArrayLen(self, target: int, nums: List[int]) -> int:
num_len = len(nums)
pre_nums = [0] * (num_len + 1)
for i in range(1, num_len + 1):
pre_nums[i] = pre_nums[i - 1] + nums[i - 1]
if pre_nums[-1] < target:
return 0
elif pre_nums[-1] == target:
return num_len
else:
min_len = num_len
left_point, right_point = 0, 1
while right_point < num_len + 1:
if pre_nums[right_point] - pre_nums[left_point] >= target:
min_len = min(min_len, right_point - left_point)
left_point += 1
else:
right_point += 1
return min_len
题目二:螺旋矩阵Ⅱ
leetcode 59 螺旋矩阵Ⅱ
非常磨人的一道模拟题,需要静下心来慢慢做(具体的思路见:代码随想录)
class Solution:
def generateMatrix(self, n: int) -> [[int]]:
left, right, top, botton = 0, n, 0, n
result = [[0 for _ in range(n)] for _ in range(n)]
num, end = 1, n * n
while num <= end:
# 从左到右
for i in range(left, right):
result[top][i] = num
num += 1
top += 1
# 从上到下
for i in range(top, botton): # 从上到下
result[i][right - 1] = num
num += 1
right -= 1
# 从右到左
for i in range(right - 1, left - 1, -1):
result[botton - 1][i] = num
num += 1
botton -= 1
# 从上到下
for i in range(botton - 1, top - 1, -1):
result[i][left] = num
num += 1
left += 1
return result
题目三:开发商购买土地
卡码coder
一道二维前缀和的题目,规定了只能画一条直线来进行区分
因此可以维护两个数组:row_presum
、column_presum
并从每个空隙中进行切分尝试,求得最小的开发商土地权重差异
数组总结
在做题过程中,数组容易出一些需要我们利用O(n)复杂度或者需要原地操作的题目。这些题目大部分都需要考虑到双指针的应用。
而双指针又能被分为快慢指针与头尾指针两种,可以根据需要自由选用(tips:快慢指针也能被用于链表的很多题目中)
同时,数组的前缀和也需要能够熟练运用,前缀和在使用过程中需要注意的是,前缀和数组对应的pre_sum[i]
是否包含了数组中的第i个数。建议构建一个使用熟练的方法,并且做一些前缀和的题目进行训练。防止笔试时的小失误。