LeetCode977 有序数组的平方(双指针)
题目链接:https://leetcode.cn/problems/squares-of-a-sorted-array/
文章讲解:https://programmercarl.com/0977.%E6%9C%89%E5%BA%8F%E6%95%B0%E7%BB%84%E7%9A%84%E5%B9%B3%E6%96%B9.html
重新构建一个平方后的数组之后,暴力调sort
库函数,时间复杂度$O(nlogn)$:
class Solution(object):
def sortedSquares(self, nums):
"""
:type nums: List[int]
:rtype: List[int]
"""
res=[]
for i in nums:
res.append(i*i)
res.sort()
return res
双指针法:
为什么想到双指针法:⭐题目特性
非递减顺序排序的含负数整数数组
nums
,平方后一定是数组两端大中间小:arrow_right:通过两端的两个指针的操作逐步向中间合拢,得到一个由大到小的数组(题目要求由小到大,新数组下标由大到小更新)
class Solution(object):
def sortedSquares(self, nums):
"""
:type nums: List[int]
:rtype: List[int]
"""
k = len(nums) - 1
res = [0] * len(nums)
i = 0 # 指向起始位置
j = len(nums) - 1 # 指向终止位置
while(i <= j):
if(nums[i] * nums[i] > nums[j] * nums[j]):
res[k] = nums[i] * nums[i]
i += 1
else:
res[k] = nums[j] * nums[j]
j -= 1
k -= 1
return res
时间复杂度为$O(n)$
LeetCode209 长度最小的子数组(滑动窗口)
题目链接:https://leetcode.cn/problems/minimum-size-subarray-sum/
暴力方法设置两个循环,时间复杂度$O(n^2)$,超时:
class Solution(object):
def minSubArrayLen(self, target, nums):
"""
:type target: int
:type nums: List[int]
:rtype: int
"""
min_length = float('inf') # 初始化为正无穷大
for i in range(len(nums)):
if nums[i] >= target:
return 1
current_sum = target - nums[i]
j = i + 1
length = 1 # 记录长度
while j < len(nums):
current_sum -= nums[j]
length += 1
if current_sum <= 0:
min_length = min(min_length, length)
break
j += 1
return 0 if min_length == float('inf') else min_length
滑动窗口
⭐用一个for循环做两个for循环做的事情,for循环中的j是滑动窗口的终止位置
when移动窗口的起始位置?
->当我们发现集合里边的所有元素和大于等于S的时候,再去移动起始位置,就可以动态的去调整起始位置,来去收集不同的区间里边的和
时间复杂度:$O(n)$
class Solution(object):
def minSubArrayLen(self, target, nums):
"""
:type target: int
:type nums: List[int]
:rtype: int
"""
i = 0 # 起始位置
sum = 0
result = float('inf')
for j in range(len(nums)): # j是终止位置
sum += nums[j]
while sum >= target: # 持续移动
subL = j - i + 1
result = min(result, subL)
sum = sum - nums[i] # 起始位置向后移动
i += 1
return result if result != float('inf') else 0
以题目中的示例来举例,s=7, 数组是[2,3,1,2,4,3],最后找到[4,3]是最短距离。
LeetCode59 螺旋矩阵II
题目链接:https://leetcode.cn/problems/spiral-matrix-ii/
文章讲解:https://programmercarl.com/0059.%E8%9E%BA%E6%97%8B%E7%9F%A9%E9%98%B5II.html
视频讲解:https://www.bilibili.com/video/BV1SL4y1N7mV/
⭐循环不变量:对每条边的处理规则一样(左闭右开)
class Solution(object):
def generateMatrix(self, n):
"""
:type n: int
:rtype: List[List[int]]
"""
nums = [[0] * n for _ in range(n)]
startx = 0
starty = 0
count = 1 # 计数
loop, mid = n // 2, n // 2 # 迭代次数、n为奇数时,矩阵的中心点
for offset in range(1, loop + 1) : # 每循环一层偏移量加1,偏移量从1开始
for j in range(starty, n - offset): # 上面一行
nums[startx][j] = count
count += 1
for i in range(startx, n - offset): # 右边一列
nums[i][n - offset] = count
count += 1
for j in range(n - offset, starty, -1): # 下面一行
nums[n - offset][j] = count
count += 1
for i in range(n - offset, startx, -1): # 左边一列
nums[i][starty] = count
count += 1
startx += 1 # 更新起始点
starty += 1
if n % 2 != 0 : # n为奇数时,填充中心点
nums[mid][mid] = count
return nums
⭐注意每次循环的边界和取值