CV炼丹师勇闯力扣训练营
代码随想录算法训练营第二天| 977.有序数组的平方 ,209.长度最小的子数组 ,59.螺旋矩阵II ,总结
一、977.有序数组的平方
给你一个按 非递减顺序 排序的整数数组 nums,返回 每个数字的平方 组成的新数组,要求也按 非递减顺序 排序。
数组其实是有序的, 只不过负数平方之后可能成为最大数了。
那么数组平方的最大值就在数组的两端,不是最左边就是最右边,不可能是中间。
此时可以考虑双指针法了,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]; 。
代码如下(Python):
# 法一、双指针
class Solution1:
def sortedSquares(self, nums: List[int]) -> List[int]:
l, r, i = 0, len(nums)-1, len(nums)-1
res = [0] * len(nums) # 结果数组初始化
while l <= r:
if nums[l] ** 2 < nums[r] ** 2: # 左右边界进行对比,找出最大值
res[i] = nums[r] ** 2
r -= 1 # 右指针往左移动
else:
res[i] = nums[l] ** 2
l += 1 # 左指针往右移动
i -= 1 # 存放结果的指针需要往前平移一位
return res
# 暴力法
class Solution2:
def sortedSquares(self, nums: List[int]) -> List[int]:
for i in range(len(nums)):
nums[i] *= nums[i]
nums.sort()
return nums
# 暴力排序法+列表推导法
class Solution:
def sortedSquares(self, nums: List[int]) -> List[int]:
return sorted(x*x for x in nums)
二、209.长度最小的子数组
给定一个含有 n 个正整数的数组和一个正整数 target 。
找出该数组中满足其总和大于等于 target 的长度最小的 子数组 [numsl, numsl+1, …, numsr-1, numsr] ,并返回其长度。如果不存在符合条件的子数组,返回 0 。
滑动窗口法
先满足条件确定终止位置,再缩小窗口确定起始位置
代码如下(Python):
class Solution:
def minSubArryLen(self, s, nums):
res = float('inf') # 长度结果初始化
sum = 0 # 滑动窗口数值和
l, r = 0, 0 # 左右指针位置
while(r < len(nums)):
sum += nums[r]
while(sum >= s):
res = min(r - l + 1, res) # 当前字串长度和之前的结果比较
sum -= nums[l]
l += 1
r += 1
return res if res != float('inf') else 0
三、59.螺旋矩阵II
给你一个正整数 n ,生成一个包含 1 到 n2 所有元素,且元素按顺时针顺序螺旋排列的 n x n 正方形矩阵 matrix 。
代码如下(Python):
class Solution:
def generateMatrix(self, n: int) -> List[List[int]]:
nums = [[0] * n for _ in range(n)]
x, y = 0, 0 # 起始点
loop, mid = n // 2, n // 2 # 迭代次数、n为奇数时,矩阵的中心点
count = 1 # 计数
for offset in range(1, loop + 1): # 每循环一层偏移量加1,偏移量从1开始
for i in range(y, n - offset): # 从左至右,左闭右开 行固定[0,3) [1,2)
nums[x][i] = count
count += 1
for i in range(x, n - offset): # 从上至下 列固定[0,3) [1,2)
nums[i][n - offset] = count
count += 1
for i in range(n - offset, y, -1): # 从右至左
nums[n - offset][i] = count
count += 1
for i in range(n - offset, x, -1): # 从下至上
nums[i][y] = count
count += 1
x += 1 # 更新起始点
y += 1
if n % 2 != 0: # n为奇数时,填充中心点
nums[mid][mid] = count
return nums
总结
- 有序数组平方用双指针
- 滑动窗口法
- 螺旋矩阵中的区间问题