977.有序数组的平方
给你一个按 非递减顺序 排序的整数数组 nums,返回 每个数字的平方 组成的新数组,要求也按 非递减顺序 排序。
示例 : 输入:nums = [-4,-1,0,3,10] 输出:[0,1,9,16,100] 解释:平方后,数组变为 [16,1,0,9,100],排序后,数组变为 [0,1,9,16,100]
本题的目标就是学习双指针。本题真的太让人想return sorted(x*x for x in nums)了,没想到拆解开后,双指针的想法真的是十分巧妙。早上看完题目和提示用双指针后,设想了一下,左指针用来计算平方,右指针用来判断和替换,想着想着又变成暴力求解了?加上一个用来存放结果的指针就看起来正常多了。
class Solution:
def sortedSquares(self, nums: List[int]) -> List[int]:
left, right, k = 0, len(nums)-1, len(nums)-1
ans = [0] * len(nums)
while left <= right:
if nums[left] * nums[left] > nums[right]*nums[right]:
ans[k] = nums[left] * nums[left]
left += 1
elif nums[left] * nums[left] <= nums[right]*nums[right]:
ans[k] = nums[right] * nums[right]
right -= 1
k -= 1
return ans
看了答案后发现
- k -= 1可以放到if的外面;
- 等于的场景可以合并到小于的场景里面;
- 时间复杂度O(n)
参考资料:
977.有序数组的平方
209.长度最小的子数组
给定一个含有 n 个正整数的数组和一个正整数 target 。
找出该数组中满足其和 ≥ target 的长度最小的 连续子数组 [numsl, numsl+1, ..., numsr-1, numsr] ,并返回其长度。如果不存在符合条件的子数组,返回 0 。
本质上是两层for循环,用滑动窗口进行优化。滑动窗口本身也是一个双指针,用一个for循环做了两个for循环做的事。
自己先写了写,周末再来整理。
class Solution:
def minSubArrayLen(self, target: int, nums: List[int]) -> int:
left, right = 0, len(nums)-1
cumsum = 0
result = float('inf')
for right in range(len(nums)):
cumsum += nums[right]
while cumsum >= target:
sublen = right - left + 1
result = min(result, sublen)
# 收缩左指针
cumsum = cumsum - nums[left]
left += 1
return 0 if result == inf else result
注:
时间复杂度是O(n),每个元素在滑动窗后进来操作一次,出去操作一次,每个元素都是被操作两次,所以时间复杂度是 2 × n 也就是O(n)。
参考资料:
209.长度最小的子数组
其他题目:
904.水果成篮
76.最小覆盖子串
59.螺旋矩阵II
给定一个正整数 n,生成一个包含 1 到 n^2 所有元素,且元素按顺时针顺序螺旋排列的正方形矩阵。
示例:
输入: 3 输出: [ [ 1, 2, 3 ], [ 8, 9, 4 ], [ 7, 6, 5 ] ]
class Solution:
def generateMatrix(self, n: int) -> List[List[int]]:
matrix = [[0 for _ in range(n)] for _ in range(n)]
upper_bound, lower_bound = 0, n - 1
left_bound, right_bound = 0, n - 1
num = 1
while num <= n * n:
if upper_bound <= lower_bound:
# 在顶部从左向右遍历
for j in range(left_bound, right_bound+1):
matrix[upper_bound][j] = num
num += 1
# 上边界下移
upper_bound += 1
if left_bound <= right_bound:
# 在右侧从上向下遍历
for i in range(upper_bound, lower_bound+1):
matrix[i][right_bound] = num
num += 1
# 右边界左移
right_bound -= 1
if upper_bound <= lower_bound:
# 在底部从右向左遍历
for j in range(right_bound, left_bound-1, -1):
matrix[lower_bound][j] = num
num += 1
# 下边界上移
lower_bound -= 1
if left_bound <= right_bound:
# 在左侧从下向上遍历
for i in range(lower_bound, upper_bound-1, -1):
matrix[i][left_bound] = num
num += 1
# 左边界右移
left_bound += 1
return matrix
考察二维码数组的遍历,已经被绕晕……
参考资料:
59.螺旋矩阵II