当前位置: 首页 > news >正文

LeetCode 面试经典 150_数组/字符串_轮转数组(6_189_C++_中等)(额外数组;转置)

LeetCode 面试经典 150_数组/字符串_轮转数组(6_189_C++_中等)

    • 题目描述:
    • 输入输出样例:
    • 题解:
      • 解题思路:
        • 思路一(额外数组):
        • 思路二(转置):
      • 代码实现
        • 代码实现(思路一(额外数组)):
        • 代码实现(思路二(转置)):
        • 以思路二为例进行调试

题目描述:

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

输入输出样例:

示例 1:
输入:nums = [1,2,3,4,5,6,7], k = 3
输出:[5,6,7,1,2,3,4]
解释
向右轮转 1 步: [7,1,2,3,4,5,6]
向右轮转 2 步: [6,7,1,2,3,4,5]
向右轮转 3 步: [5,6,7,1,2,3,4]

示例 2:
输入:nums = [-1,-100,3,99], k = 2
输出:[3,99,-1,-100]
解释
向右轮转 1 步: [99,-1,-100,3]
向右轮转 2 步: [3,99,-1,-100]

提示:
1 <= nums.length <= 105
-231 <= nums[i] <= 231 - 1
0 <= k <= 105

题解:

解题思路:

思路一(额外数组):

1、我们可以采用额外的数组来暂时存储从后方移动向前方的k个元素,再将前方剩余的元素移动到后方,再将数组暂存的元素放入前方。

2、以nums = [1,2,3,4,5,6,7], k = 3为例
① k=3意味着末尾有三个元素移到前端,且三个元素相对位置不变。
② 我们可以使用一个额外的空间tmp存储末尾移动到前端的元素tmp=[5,6,7]。
③ 则此时nums中的元素可以进行移动nums=[1,2,3,1,2,3,4]。
④ 最后我们将tmp中的元素放在nums的前端 nums=[5,6,7,1,2,3,4]

3、复杂度分析:
① 时间复杂度:O(N),其中 N 是数组中的元素数量。
② 空间复杂度:O(N),取决于k%nums.size()的大小,取值0~N-1,所以为O(N)。

思路二(转置):

1、先将数组进行翻转,再将两个分数组进行翻转。
:nums = [1,2,3,4,5,6,7], k = 3。
① 先将nums翻转[7,6,5,4,3,2,1]
②再将前k=3个元素翻转,后续元素也翻转[5,6,7,1,2,3,4] 。

2、复杂度分析
① 时间复杂度:O(N),其中 N 是数组中的元素数量。因翻转数组两次。
② 空间复杂度:O(1),我们只需要常数空间存放若干变量。

代码实现

代码实现(思路一(额外数组)):
class Solution1 {
public:void rotate(vector<int>& nums, int k) {// 如果旋转步数k与数组长度相同,则不需要进行任何操作if (nums.size() == k){return ;}// 如果k大于数组长度,将k缩小为k % nums.size(),因为旋转k次和旋转k % nums.size()次效果相同else if(k > nums.size()){k = k % nums.size();}// 创建一个临时数组,用于保存旋转后末尾的部分vector<int> tmp;// 将数组的后k个元素存入临时数组tmpfor (int i = nums.size() - k; i < nums.size(); i++){tmp.push_back(nums[i]);}// 将数组的前n-k个元素(即从0到nums.size()-k-1的位置)往后移动k位for (int j = nums.size() - k - 1; j >= 0 ; j--){nums[j + k] = nums[j];}// 将临时数组tmp的前k个元素放回数组的前面for (int n = 0; n < k; n++){nums[n] = tmp[n];}}
};
代码实现(思路二(转置)):
class Solution2 {
private:// 反转数组的辅助函数void reverse(vector<int>& nums, int left, int right){int tmp;// 通过交换元素来反转数组的指定部分while (left < right){tmp = nums[left];          // 临时保存左边的元素nums[left] = nums[right];  // 将右边的元素放到左边nums[right] = tmp;         // 将临时保存的左边元素放到右边left++;                    // 左指针向右移动right--;                   // 右指针向左移动}}public:void rotate(vector<int>& nums, int k) {// 如果数组的大小与旋转次数k相等,直接返回,因为旋转后数组不会变化if (nums.size() == k){return ;}// 如果k大于数组的大小,减少不必要的旋转else if (k > nums.size()){k = k % nums.size();}// 步骤1: 反转整个数组reverse(nums, 0, nums.size() - 1);// 步骤2: 反转数组的前k个元素reverse(nums, 0, k - 1);// 步骤3: 反转数组的剩余部分reverse(nums, k, nums.size() - 1);}
};
以思路二为例进行调试
#include<iostream>
#include<vector>
using namespace std;class Solution2 {
private:// 反转数组的辅助函数void reverse(vector<int>& nums, int left, int right){int tmp;// 通过交换元素来反转数组的指定部分while (left < right){tmp = nums[left];          // 临时保存左边的元素nums[left] = nums[right];  // 将右边的元素放到左边nums[right] = tmp;         // 将临时保存的左边元素放到右边left++;                    // 左指针向右移动right--;                   // 右指针向左移动}}public:void rotate(vector<int>& nums, int k) {// 如果数组的大小与旋转次数k相等,直接返回,因为旋转后数组不会变化if (nums.size() == k){return ;}// 如果k大于数组的大小,减少不必要的旋转else if (k > nums.size()){k = k % nums.size();}// 步骤1: 反转整个数组reverse(nums, 0, nums.size() - 1);// 步骤2: 反转数组的前k个元素reverse(nums, 0, k - 1);// 步骤3: 反转数组的剩余部分reverse(nums, k, nums.size() - 1);}
};int main(int argc, char const *argv[])
{vector<int> nums={1,2,3,4,5,6,7};int k=3;Solution2 s;s.rotate(nums,k);for(auto const &i:nums){cout<<i<<" ";}return 0;
}

LeetCode 面试经典 150_数组/字符串_轮转数组(6_189)原题链接
欢迎大家和我沟通交流(✿◠‿◠)

http://www.dtcms.com/a/305895.html

相关文章:

  • 磁盘io查看命令iostat与网络连接查看命令netstat
  • Apache HTTP Server 2.4.50 路径穿越漏洞(CVE-2021-42013)
  • 矩阵指数函数 e^A
  • AR技术赋能航空维修:精度与效率的飞跃
  • 基于Catboost的铁路交通数据分析及列车延误预测系统的设计与实现【全国城市可选、欠采样技术】
  • Three.js 与 WebXR:初识 VR/AR 开发
  • nest generate从入门到实战
  • 6.Origin2021如何绘制Y轴截断图?
  • Java 笔记 封装(Encapsulation)
  • 常见存储卡类型及对比
  • Elasticsearch 索引管理 API 实战:涵盖创建、查看、修改、删除及别名
  • 10 分钟上手 Elasticsearch 语义搜索(Serverless Cloud 本地双版本教程)
  • 在 Kubernetes 上部署 Label Studio
  • 汽车免拆诊断案例 | 免拆诊断发动机起动困难故障2例
  • Visual Studio Code 使用指南 (2025年版)
  • lesson28:Python单例模式全解析:从基础实现到企业级最佳实践
  • 【网络工程师软考版】路由协议 + ACL
  • 网络资源模板--基于Android Studio 实现的图书商城App
  • 如何不让android studio自动换行
  • UDP通讯和TCP通讯的区别-UDP(用户数据报协议)和 TCP(传输控制协议)
  • 第十七章 追新词
  • Python 闭包(Closure) 特性剖析
  • Linux ps -ef 命令解析
  • 三十二、【Linux网站服务器】搭建httpd服务器演示虚拟主机配置、网页重定向功能
  • STM32学习记录--Day3
  • ubuntu编译opendds
  • STM32CubeMX 生成时钟获取函数的分析
  • OmniParser:提升工作效率的视觉界面解析工具
  • react+ant design怎么样式穿透-tooltip怎么去掉箭头
  • 地下停车场照明节能:技术方案与价值重构