长度最小的子数组

给定一个含有 n 个正整数的数组和一个正整数 s ,找出该数组中满足其和 ≥ s 的长度最小的 连续 子数组,并返回其长度。如果不存在符合条件的子数组,返回 0。

示例:

  • 输入:s = 7, nums = [2,3,1,2,4,3]
  • 输出:2
  • 解释:子数组 [4,3] 是该条件下的长度最小的子数组。

提示:

  • 1 <= target <= 10^9
  • 1 <= nums.length <= 10^5
  • 1 <= nums[i] <= 10^5
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class Solution:
def minSubArrayLen(self, target: int, nums: List[int]) -> int:
length = len(nums)
left = 0
right = 0 #左闭右闭
min_nums = length + 1
sum_n = 0
while right < length:
sum_n += nums[right]
while sum_n >= target:
min_nums = min(right - left + 1,min_nums)
sum_n -= nums[left]
left += 1
right += 1
return min_nums if min_nums != length + 1 else 0

这道题可以用滑动窗口的方式来实现
设置两个指针left和right,分别指向子数组的左右边界。
初始的时候设置两个指针都是0,即指向数组的第一个元素。
然后通过移动右指针来扩大子数组的大小直到子数组的和大于等于target。
这个时候我们得到的就是在起点为0条件下获得的最小子数组长度。
因此我们可以移动左指针的位置,一方面可以缩小子数组的长度,另一方面也是调整子数组的起点。
如果减去初始的左指针指向的元素后子数组的和仍然大于等于target,那么我们就可以继续移动左指针,直到子数组的和小于target,当然在这过程中要更新最小数组长度。
如果子数组的和小于target了那我们就继续移动右指针,扩大子数组的大小。重复这个过程到循环结束

1
2
3
4
5
6
7
8
9
10
11
12
class Solution:
def minSubArrayLen(self, target: int, nums: List[int]) -> int:
length = len(nums)
min_nums = length + 1
for i in range(length):
sum_n = 0
for j in range(i,length):
sum_n += nums[j]
if sum_n >= target:
min_nums = min(min_nums,j-i+1)
break
return min_nums if min_nums != length + 1 else 0

暴力解法就是用两个for循环,一个for循环遍历数组的每个元素,另一个for循环遍历从当前元素开始的所有子数组,计算子数组的和是否大于等于target。超时了就是了

螺旋矩阵II

给定一个正整数 n,生成一个包含 1 到 n^2 所有元素,且元素按顺时针顺序螺旋排列的正方形矩阵。

示例:

  • 输入: 3 输出: [ [ 1, 2, 3 ], [ 8, 9, 4 ], [ 7, 6, 5 ] ]
    题目示例
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
class Solution:
def generateMatrix(self, n: int) -> List[List[int]]:
nums=[[0]*n for _ in range(n)] # 创建一个n*n的空列表
start_x,start_y = 0,0 #每一圈的起始位置,注意是每一圈的,因此转完一圈后起始位置的x、y都要加一 ,x表示行数,y表示列数
count = 1 #表示转到哪个数字
offset = 1 #偏移量,其实我觉得也是圈数
while n // 2 > offset-1: #转一圈消耗两层啦
for j in range(start_y,n-offset):
nums[start_x][j] = count
count += 1
for i in range(start_x,n-offset):
nums[i][n-offset] = count
count += 1
for j in range(n-offset,start_y,-1):
nums[n-offset][j] = count
count += 1
for i in range(n-offset,start_x,-1):
nums[i][start_y] = count
count += 1
start_x += 1
start_y += 1
offset += 1
if n %2 == 1:
nums[n//2][n//2] = count
return nums

这道题目的核心在处理边界问题,特别在顶点的取否上,这里我们采用左闭右开的方式,然后明白转一圈消耗两层,然后每一圈更新起始位置和偏移量。

扩展题看了思路,但是我自己还没憋出来,等晚上再试试