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

🔥个人主页: 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)\) 原地操作,但逻辑
相关推荐
代码AI弗森1 天前
一文理清楚“算力申请 / 成本测算 / 并发评估”
java·服务器·数据库
Old Uncle Tom1 天前
OpenClaw 记忆系统 -- 记忆预加载
java·数据结构·算法·agent
会编程的土豆1 天前
洛谷题单入门1 顺序结构
数据结构·算法·golang
小小小米粒1 天前
Collection单列集合、Map(Key - Value)双列集合,多继承实现。
java·开发语言·windows
生信碱移1 天前
PACells:这个方法可以鉴定疾病/预后相关的重要细胞亚群,作者提供的代码流程可以学习起来了,甚至兼容转录组与 ATAC 两种数据类型!
人工智能·学习·算法·机器学习·数据挖掘·数据分析·r语言
智者知已应修善业1 天前
【51单片机中的打飞机设计】2023-8-25
c++·经验分享·笔记·算法·51单片机
摇滚侠1 天前
expdp 查看帮助
java·数据库·oracle
:1211 天前
java基础
java·开发语言
圣保罗的大教堂1 天前
leetcode 1855. 下标对中的最大距离 中等
leetcode
曹牧1 天前
Spring:@RequestMapping注解,匹配的顺序与上下文无关
java·后端·spring