旋转数组
数组 三步翻转法题目描述
给定一个数组 nums,将数组中的元素向右轮转 k 个位置,其中 k 是非负数。要求使用 原地 算法,即不使用额外的数组空间。
思路分析
处理数组旋转问题时,最直观的想法是使用额外的空间来辅助。然而,如果我们希望在原数组上进行修改,就需要寻找元素索引变换的规律。当数组向右移动 k 个位置时,尾部的元素会循环回到数组头部。这种周期性的位移可以通过取模运算来简化,因为旋转一个数组长度的倍数相当于没有变化。
三步翻转法是一种优雅且高效的解法。它基于一个有趣的观察:我们可以通过局部的翻转来实现全局的位移。首先,我们将整个数组进行翻转,这样数组的头部和尾部位置就完全颠倒了。随后,我们只需要分别针对前 k 个元素和剩余的元素进行局部翻转,就能让它们回到正确的相对顺序。这种方法巧妙地利用了翻转操作的对称性,只需遍历数组两次(一次整体,一次局部),即可在不借用辅助数组的情况下完成原位的旋转任务。
示例代码
复杂度分析
- 时间复杂度:
O(n),其中n为数组长度。总共进行了三次翻转操作,每次翻转的时间复杂度与处理的子数组长度成正比,总的时间复杂度仍为线性级别。 - 空间复杂度:
O(1)。只使用了常数个辅助变量,满足原地修改的要求。
示例演示
以 nums = [1, 2, 3, 4, 5, 6, 7] 且 k = 3 为例,核心步骤如下:
- 取模处理:
k = 3 % 7 = 3。 - 翻转整个数组:
[1, 2, 3, 4, 5, 6, 7]➡️[7, 6, 5, 4, 3, 2, 1] - 翻转前 k 个元素(索引 0 到 2):
[7, 6, 5, 4, 3, 2, 1]➡️[5, 6, 7, 4, 3, 2, 1] - 翻转剩余元素(索引 3 到 6):
[5, 6, 7, 4, 3, 2, 1]➡️[5, 6, 7, 1, 2, 3, 4]
最终结果为 [5, 6, 7, 1, 2, 3, 4]。