目录
今天继续进行数组的练习,完成以下3道题
977.有序数组的平方 ,209.长度最小的子数组 ,59.螺旋矩阵II ,总结
一、leetcode 977.有序数组的平方
双指针解法:关键是理解好前后指针
数组其实是有序的, 只不过负数平方之后可能成为最大数了。
那么数组平方的最大值就在数组的两端,不是最左边就是最右边,不可能是中间。
此时可以考虑双指针法了,i指向起始位置,j指向终止位置。
定义一个新数组result,和A数组一样的大小,让k指向result数组终止位置。
如果A[i] * A[i] < A[j] * A[j]
那么result[k--] = A[j] * A[j];
。
如果A[i] * A[i] >= A[j] * A[j]
那么result[k--] = A[i] * A[i];
代码:
class Solution:
def sortedSquares(self, nums: List[int]) -> List[int]:
n = len(nums)
i = 0
j = n-1
k = n-1
res = [0 for i in range(n)]
while i <= j: # 注意1==j 仍然是有意义的
if nums[i]*nums[i] < nums[j]*nums[j]:
res[k] = nums[j]*nums[j]
j-=1
else:
res[k] = nums[i] * nums[i]
i+=1
k -= 1
return res
二、leetcode 209.长度最小的子数组
给定一个含有 n
个正整数的数组和一个正整数 target
。
找出该数组中满足其和 ≥ target
的长度最小的 连续子数组 [numsl, numsl+1, ..., numsr-1, numsr]
,并返回其长度。如果不存在符合条件的子数组,返回 0
。
输入:target = 7, nums = [2,3,1,2,4,3] 输出:2 解释:子数组[4,3]
是该条件下的长度最小的子数组。
(1)暴力求解:
两个for 循环,然后不断的寻找符合条件的子序列,时间复杂度为,通过不了,因此得想一个能减少遍历的方法。
(2)双指针(滑动窗口)
从暴力求解法可以看出,其实可以知道很多遍历是不需要的。因为要求连续的子集,因此只需要确定好一个窗口,然后在窗口内判断是否符合要求。因此要实现滑动窗口解决本题,需要注意以下几点:
- 窗口内是什么?
- 如何移动窗口的起始指针?
- 如何移动窗口的结束指针?
窗口就是 满足其和 ≥ s 的长度最小的 连续 子数组。
窗口的起始指针如何移动:如果当前窗口的总和>=target了,此时就要开始缩圈了,窗口的起始置针就要往前移动,直到不满足条件了,后面就得移动结束指针
窗口的结束指针如何移动:窗口的结束位置就是遍历数组的指针,也就是for循环里的索引。
解题的关键在于 窗口的起始位置如何移动,如图所示:
代码
class Solution:
def minSubArrayLen(self, target: int, nums: List[int]) -> int:
n = len(nums)
if n==0:
return 0
min_len = n+1
j=0
s=0
for i in range(0,n):
s += nums[i]
while s>=target:
min_len = min(min_len,i-j+1)
s -= nums[j]
j+=1
if min_len <n+1:
return min_len
else:
return 0
三、leetcode 59. 螺旋矩阵 II
给你一个正整数 n
,生成一个包含 1
到 n2
所有元素,且元素按顺时针顺序螺旋排列的 n x n
正方形矩阵 matrix
。
示例
输入:n = 3
输出:[[1,2,3],[8,9,4],[7,6,5]]
解体思路
模拟顺时针画矩阵的过程:
- 填充上行从左到右
- 填充右列从上到下
- 填充下行从右到左
- 填充左列从下到上
由外向内一圈一圈这么画下去。
代码
class Solution:
def generateMatrix(self, n: int) -> List[List[int]]:
res = [[0 for i in range(n)] for j in range(n)]
startx = 0
starty = 0
loop = n//2
mid = n//2
offset = 1
count = 1
while loop>0:
i = startx
j = starty
# 填充上行从左到右
while j<n-offset:
res[startx][j] = count
count += 1
j+=1
while i<n-offset:
res[i][j] = count
count += 1
i+=1
while j>starty:
res[i][j] = count
count +=1
j -= 1
while i>startx:
res[i][j] = count
count += 1
i-=1
loop -=1
startx += 1
starty += 1
offset += 1
if n%2:
res[mid][mid] = count
return res