☰
LeetCode 189题:数组轮转的三种解法与优化
2026/11/6 7:19:26 网站建设 项目流程

1. 问题描述与核心挑战

LeetCode 189题要求我们将一个数组中的元素向右轮转k个位置。举个具体例子,给定数组[1,2,3,4,5,6,7],当k=3时,轮转后的结果应该是[5,6,7,1,2,3,4]。这个问题看似简单,但实际处理时需要特别注意几个关键点:

首先,k的值可能大于数组长度。比如数组长度为7而k=10时,实际上只需要轮转10%7=3次即可。其次,题目要求使用空间复杂度为O(1)的原地算法,这就排除了直接使用额外数组存储结果的简单解法。最后,对于大规模数组,算法的时间效率也是需要考虑的重要因素。

2. 基础解法:使用额外空间

2.1 实现思路

最直观的解法是创建一个新数组,将原数组的后k个元素放到新数组的前面,再把原数组的前n-k个元素放到新数组的后面。这种方法简单易懂,时间复杂度为O(n),但空间复杂度也是O(n),不符合题目对空间的要求。

void rotate(int* nums, int numsSize, int k) { k = k % numsSize; int* temp = (int*)malloc(sizeof(int) * numsSize); // 复制后k个元素 memcpy(temp, nums + numsSize - k, sizeof(int) * k); // 复制前n-k个元素 memcpy(temp + k, nums, sizeof(int) * (numsSize - k)); // 将结果复制回原数组 memcpy(nums, temp, sizeof(int) * numsSize); free(temp); }

2.2 优缺点分析

这种方法的优点是实现简单,不易出错。缺点是使用了额外的O(n)空间,这在内存受限的环境中可能成为问题。此外,它需要进行三次数组拷贝操作,虽然时间复杂度是线性的,但实际执行时间可能比其他方法稍长。

3. 原地轮转:三次反转法

3.1 算法原理

三次反转法是一种巧妙的原地算法,它通过三次反转操作实现数组轮转:

  1. 反转整个数组
  2. 反转前k个元素
  3. 反转剩下的n-k个元素

以[1,2,3,4,5,6,7]和k=3为例:

  1. 整体反转得到[7,6,5,4,3,2,1]
  2. 反转前3个得到[5,6,7,4,3,2,1]
  3. 反转后4个得到[5,6,7,1,2,3,4]

3.2 代码实现

void reverse(int* nums, int start, int end) { while (start < end) { int temp = nums[start]; nums[start] = nums[end]; nums[end] = temp; start++; end--; } } void rotate(int* nums, int numsSize, int k) { k = k % numsSize; reverse(nums, 0, numsSize - 1); reverse(nums, 0, k - 1); reverse(nums, k, numsSize - 1); }

3.3 复杂度分析

这种方法的时间复杂度是O(n),因为每个元素被交换了两次。空间复杂度是O(1),只使用了常数级别的额外空间,完全符合题目要求。

4. 环状替换法

4.1 算法思想

环状替换法将数组视为一个环,每次将一个元素放到它最终应该在的位置,同时保存被替换的元素,继续处理直到所有元素都被放置到正确位置。这种方法需要处理多个环的情况。

4.2 实现细节

void rotate(int* nums, int numsSize, int k) { k = k % numsSize; int count = 0; for (int start = 0; count < numsSize; start++) { int current = start; int prev = nums[start]; do { int next = (current + k) % numsSize; int temp = nums[next]; nums[next] = prev; prev = temp; current = next; count++; } while (start != current); } }

4.3 性能考量

环状替换法的时间复杂度也是O(n),每个元素只被移动一次。空间复杂度为O(1)。这种方法在理论上很优雅,但在实际编码时需要考虑循环终止条件,实现起来相对复杂一些。

5. 方法比较与选择建议

5.1 性能对比

方法时间复杂度空间复杂度实现难度适用场景
额外空间法O(n)O(n)简单内存不敏感场景
三次反转法O(n)O(1)中等通用场景
环状替换法O(n)O(1)较难理论最优但难调试

5.2 选择建议

对于面试或竞赛,三次反转法通常是首选,因为它平衡了实现难度和性能要求。在实际工程中,如果内存不是问题,使用额外空间的方法可能更可靠。环状替换法更适合展示对算法的深入理解。

6. 常见错误与调试技巧

6.1 典型错误

  1. 忽略k大于数组长度的情况
  2. 在三次反转法中搞错反转的区间
  3. 环状替换法中循环条件处理不当导致死循环

6.2 调试建议

  • 对于边界情况(k=0,k=数组长度)单独测试
  • 使用小数组(3-5个元素)手动验证算法步骤
  • 打印中间结果检查每一步是否符合预期

7. 扩展思考

这个问题可以延伸到字符串旋转、链表旋转等变种。三次反转的思想也可以应用于其他需要循环移动的场景。例如,在图像处理中旋转像素矩阵时,类似的算法思想也同样适用。

在实际工程中,我们可能还需要考虑数组非常大的情况,这时算法的缓存友好性就变得重要。三次反转法在这方面表现较好,因为它按顺序访问内存,具有良好的局部性。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询