双指针
977. 有序数组的平方
https://leetcode.cn/problems/squares-of-a-sorted-array/
数组 双指针 排序
给你一个按
非递减顺序排序的整数数组nums,返回每个数字的平方组成的新数组,要求也按非递减顺序排序。
方法一:暴力排序
方法二:双指针法
代码随想录思路:逆向思维 (官方解法-方法三:双指针)
数组其实是有序的, 只不过负数平方之后可能成为最大数了。
那么数组平方的最大值就在数组的两端,不是最左边就是最右边,不可能是中间。
此时可以考虑双指针法了,iii指向起始位置,jjj指向终止位置。
定义一个新数组result,和A数组一样的大小,让k指向result数组终止位置。
如果A[i]∗A[i]<A[j]∗A[j]A[i] * A[i] < A[j] * A[j]A[i]∗A[i]<A[j]∗A[j],那么result[k]=A[j]∗A[j]result[k] = A[j] * A[j]result[k]=A[j]∗A[j]
如果A[i]∗A[i]>=A[j]∗A[j]A[i] * A[i] >= A[j] * A[j]A[i]∗A[i]>=A[j]∗A[j],那么result[k]=A[i]∗A[i]result[k] = A[i] * A[i]result[k]=A[i]∗A[i]
class Solution:
def sortedSquares(self, nums: List[int]) -> List[int]:
# 双指针法
n = len(nums)
left, right, k = 0, n - 1, n - 1
result = [0] * n
while left <= right:
if nums[left] * nums[left] > nums[right] * nums[right]:
result[k] = nums[left] * nums[left]
left += 1
else:
result[k] = nums[right] * nums[right]
right -= 1
k -= 1
return result
复杂度分析
时间复杂度:O(n)O(n)O(n),其中 n 是数组 nums\textit{nums}nums 的长度。
空间复杂度:O(1)O(1)O(1)。除了存储答案的数组以外,我们只需要维护常量空间。
189.轮转数组
https://leetcode.cn/problems/rotate-array/
数组 数学 双指针
给你一个数组,将数组中的元素向右轮转 k 个位置,其中 k 是非负数。
原地算法
方法一:先反转整个数组,再反转局部区间
本题是右旋转,其实就是反转的顺序改动一下,优先反转整个数组,步骤如下:
- 反转整个数组
- 反转区间为前k的数组
- 反转区间为k到末尾的数组
这是一个重要的思想,可以用到很多需要反转的题目中。
注:本题还有一个小陷阱,题目输入中,如果k大于nums.size了应该怎么办?
例如,1,2,3,4,5,6,7 如果右移动15次的话,是 7 1 2 3 4 5 6 。
所以其实就是右移 k % nums.size() 次,即:15 % 7 = 1
复杂度分析
时间复杂度:O(n)O(n)O(n),其中 n 为数组的长度。每个元素被翻转两次,一共 n 个元素,因此总时间复杂度为 O(2n)=O(n)O(2n)=O(n)O(2n)=O(n)。
空间复杂度:O(1)O(1)O(1)。
这篇博客探讨了如何使用双指针法解决两个经典的数组操作问题:有序数组的平方排序和轮转数组。在有序数组的平方问题中,通过双指针从两端开始比较并填充结果数组,确保了非递减的顺序。而在轮转数组问题中,通过两次反转实现了原地旋转,解决了空间复杂度的要求。这两个问题都展示了双指针在数组操作中的高效性和灵活性。
198

被折叠的 条评论
为什么被折叠?



