普通数组----轮转数组

🔥个人主页: Milestone-里程碑

❄️个人专栏: <<力扣hot100>> <<C++>><<Linux>>

<<Git>><<MySQL>>

🌟心向往之行必能至

题目描述

给定一个整数数组 nums,将数组中的元素向右轮转 k 个位置,其中 k 是非负数。

示例 1 输入:nums = [1,2,3,4,5,6,7], k = 3输出:[5,6,7,1,2,3,4]解释:向右轮转 3 步后,数组末尾的 3 个元素移动到了数组开头。

示例 2 输入:nums = [-1,-100,3,99], k = 2输出:[3,99,-1,-100]


解法一:使用额外数组(直观易懂)

这是最容易想到的方法,通过一个临时数组来存储轮转后的结果,再拷贝回原数组。

思路

  1. 计算有效轮转步数 x = k % nums.size(),避免 k 大于数组长度时的无效轮转。
  2. 创建临时数组 temp,将原数组的后 x 个元素和前 n-x 个元素依次放入。
  3. 将临时数组的内容拷贝回原数组。

代码

cpp

复制代码
void rotate(vector<int>& nums, int k) {
    int n = nums.size();
    int x = k % n;
    vector<int> temp(n);
    for (int i = 0; i < n; ++i) {
        temp[(i + x) % n] = nums[i];
    }
    nums = temp;
}

复杂度分析

  • 时间复杂度:\(O(n)\),遍历一次数组。
  • 空间复杂度:\(O(n)\),需要额外的临时数组存储结果。

解法二:三次反转(原地算法,最优解)

这是这道题的最优解法,不需要额外空间,仅通过三次反转操作就可以完成轮转。

思路

  1. 计算有效步数x = k % nums.size(),处理 k 大于数组长度的情况。
  2. 第一次反转:将整个数组反转。
  3. 第二次反转 :将数组的前 x 个元素反转。
  4. 第三次反转 :将数组的剩余 n-x 个元素反转。

示例演示 (以 nums = [1,2,3,4,5,6,7], k=3 为例)

  • 原数组:[1,2,3,4,5,6,7]
  • 整体反转:[7,6,5,4,3,2,1]
  • 反转前 3 个:[5,6,7,4,3,2,1]
  • 反转后 4 个:[5,6,7,1,2,3,4]

代码

cpp

复制代码
#include <vector>
#include <algorithm>
using namespace std;

class Solution {
public:
    void rotate(vector<int>& nums, int k) {
        int n = nums.size();
        int x = k % n;
        if (x == 0) return;
        // 1. 反转整个数组
        reverse(nums.begin(), nums.end());
        // 2. 反转前x个元素
        reverse(nums.begin(), nums.begin() + x);
        // 3. 反转剩余元素
        reverse(nums.begin() + x, nums.end());
    }
};

复杂度分析

  • 时间复杂度:\(O(n)\),三次反转操作的总时间为 \(O(n)\)。
  • 空间复杂度:\(O(1)\),仅使用常量级的额外空间。

解法三:环状替换(原地算法,进阶思路)

这是另一种原地算法,通过计算每个元素的目标位置,以环状的方式进行元素替换。

思路

  1. 计算有效步数 x = k % nums.size()
  2. 从起始位置开始,将当前元素放到它轮转后的目标位置,再将目标位置的元素放到它的目标位置,直到回到起始位置。
  3. 如果一轮替换没有覆盖所有元素,则从下一个位置开始重复上述过程。

复杂度分析

  • 时间复杂度:\(O(n)\),每个元素只被移动一次。
  • 空间复杂度:\(O(1)\),仅使用常量级的额外空间。

三种解法对比

解法 时间复杂度 空间复杂度 特点
额外数组 \(O(n)\) \(O(n)\) 思路简单,容易实现,但需要额外空间
三次反转 \(O(n)\) \(O(1)\) 最优解,原地操作,代码简洁高效
环状替换 \(O(n)\) \(O(1)\) 原地操作,但逻辑
相关推荐
zander258几秒前
114. 二叉树展开为链表
数据结构·链表·深度优先
TDengine (老段)14 分钟前
TDengine 免费版说明
java·大数据·数据库·物联网·时序数据库·tdengine
乐观勇敢坚强的老彭17 分钟前
信奥C++一维数组笔记
开发语言·c++·笔记
码上有光18 分钟前
异常和智能指针
java·大数据·c++·servlet·异常·智能指针
变量未定义~21 分钟前
最小生成树1(Prim模板)、最小生成树2(kruskal模板)、最近公共祖先(模板)
算法
这就是佬们吗25 分钟前
Python入门⑤-异常处理、文件操作与实战项目
开发语言·数据库·python·算法·pycharm
王维同学30 分钟前
[原创][Windows C++]Explorer Shell 扩展、图标覆盖与 COM 服务器定位
c++·windows·注册表
LONGZETECH32 分钟前
新能源汽车充电设备装配与调试仿真教学软件 技术架构与核心实现解析
大数据·算法·3d·unity·架构·汽车
code_pgf34 分钟前
C++ 工程架构设计规范
c++·机器人
自学小白菜34 分钟前
关于提升机器学习算法做预测回归任务精度的方法分享
算法·机器学习·回归·提升精度