题目传送门:轮转数组

题目详情:

给你一个数组,将数组中的元素向右轮转 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 <= 10^5
  • -2^31 <= nums[i] <= 2^31 - 1
  • 0 <= k <= 10^5

题目分析和代码:

起初并没有看到提示部分,自认为给的数组并不会很大,然后也没有深入思考,立刻就将代码写了出来。

初始超时代码(c++):

class Solution {
public:void rotate(vector<int>& nums, int k) {int length=nums.size()-1;//数组下标最大值while(k)//数组每向右移动一次执行一次循环直至移动k次{int t=nums[length];for(int i=length;i>0;i--)//将数组第一个元素至倒数第二个元素中的每个元素都向右移动一位{nums[i]=nums[i-1];}nums[0]=t;k--;}}
};

时间复杂度为O(k*n),空间复杂度为O(1),虽然空间复杂度低但时间复杂度直接拉满了,题目数组范围太大因此在第35个测试用例超时了,当时我还很奇怪,点开查看最后的输入时才发现原来数组范围居然会这么大,开始认真思考解题方法了。

拿示例一来分析:输入: nums = [1,2,3,4,5,6,7], k = 3   输出: [5,6,7,1,2,3,4]

先将数组下标标出来:()内为数组下标

输入: nums = [1(0),2(1),3(2),4(3),5(4),6(5),7(6)]

输出:              [5(0),6(1),7(2),1(3),2(4),3(5),4(6)]

从上面我们可以看出数组下标为0的1移动到了数组下标为3的位置,数组下标为1的2则移动到了数组下标为4的位置,数组下标为6的7移动到了数组下标为2的位置,从其中我们可以发现元素下标的移动规律为:移动到(数组下标n+k)%数组长度的数组位置,(0+3)%7=3,(6+3)%7=2;找到规律后再将答案放到一个新开辟空间的数组中最后再转到原数组中,时间复杂度为O(n),空间复杂度为O(n)

第一次ac代码(c++):

class Solution {
public:void rotate(vector<int>& nums, int k) {int length=nums.size();vector<int>ans(length,0);for(int i=0;i<=length-1;i++){int dis=(i+k)%length;ans[dis]=nums[i];}for(int i=0;i<=length-1;i++){nums[i]=ans[i];}}
};

这样发现题目还是比较简单的,但是题目进阶要求时间复杂度为O(n),空间复杂度为O(1),空间复杂度为O(1)确实有点困难,看了官方题解三后发现居然还有这么神奇的方法,下面就简单讲解一下数组翻转的方法。

还是拿示例一来分析:输入: nums = [1,2,3,4,5,6,7], k = 3   输出: [5,6,7,1,2,3,4]

我们发现尾部k%数组长度的元素(5,6,7)移动到了数组头部,而其余元素则向后移动了k%数组长度的位置。

我们可以先将数组所有元素进行翻转,这样尾部的元素就会到达数组头部位置,然后再将头部前k%数组长度的元素翻转保证数组元素的顺序不变,然后再将其他元素进行翻转。

输入: nums = [1,2,3,4,5,6,7], k = 3

先将数组所有元素进行翻转:                                           nums = [7,6,5,4,3,2,1]

然后再将头部3%7(7为数组长度)=前3个元素进行翻转:  nums = [5,6,7,4,3,2,1]

再将其他元素进行翻转:                                                  nums = [5,6,7,1,2,3,4]

输出: [5,6,7,1,2,3,4]

数组翻转的代码(c++):

class Solution {
public:void rotate(vector<int>& nums, int k) {k %= nums.size();reverse(nums.begin(),nums.end());//翻转整个数组元素reverse(nums.begin(),nums.begin()+k);//翻转前k个元素reverse(nums.begin()+k,nums.end());//翻转其余元素}
};

reverse为c++函数,可以实现翻转数组,字符串,向量,使用时需要包含头文件<algorithm> 。

使用方法:翻转数组:reverse(a,a+n)n为数组元素个数;翻转vector中的元素或字符串时则为reverse(vec.begin() ,vec.end() ) 和 reverse(str.begin() ,str.end() )。

题目要求将数组进行向右旋转,如果是向左旋转的话只用将第一行翻转代码改到最后一行就行了,即为先翻转前n个元素,再翻转其余元素,最后翻转数组所有元素。

时间复杂度为O(n),空间复杂度为O(1)

环状替换代码(c++):

我们从初始位置 0 开始,最初令pre=nums[0]。可以得出位置 0 的元素会放到 (0+k)%n的位置,令 x= (0+k)%n,然后交换 pre 和 nums[x],完成位置 x 的更新。然后,我们继续研究位置 x,并交换 pre 和 nums[(x+k)%n],从而完成下一个位置的更新。如果回到初始起点0时还有元素未进行翻转,则将起点位置+1,然后重复上述内容直至一共翻转了n个元素(翻转完成)。

class Solution {
public:void rotate(vector<int>& nums, int k) {int length=nums.size(),count=length;int i=0,pos=0,pre=nums[pos];//pre会不断更新成被覆盖的元素if (k % length == 0)return;while (count--)//一共要对n个元素进行翻转,n为元素个数 {pos = (pos + k) % length;swap(nums[pos], pre);if (pos == i)//如果回到起点且还有未遍历过的元素时{pos = ++i;pre = nums[pos];}}}
};

时间复杂度为O(n),空间复杂度为O(1)

计算机204 zjr

LeetCode 189.轮转数组 (双指针)相关推荐

  1. LeetCode 189. 轮转数组

  2. LeetCode 189.轮转数组

    文章目录

  3. LeetCode 189. 旋转数组(环形替换)

    1. 题目 给定一个数组,将数组中的元素向右移动 k 个位置,其中 k 是非负数. 示例 1:输入: [1,2,3,4,5,6,7] 和 k = 3 输出: [5,6,7,1,2,3,4] 解释: 向 ...

  4. Leetcode 189. 旋转数组 解题思路及C++实现

    方法一:暴力方法 解题思路: 用栈存储后面的 k 个元素,然后将 nums 数组的元素往后挪 k 位,然后再将栈中的元素存进nums数组中. class Solution { public:void ...

  5. Leetcode 189. 旋转数组 (每日一题 20210909)

    给定一个数组,将数组中的元素向右移动 k 个位置,其中 k 是非负数.进阶:尽可能想出更多的解决方案,至少有三种不同的方法可以解决这个问题. 你可以使用空间复杂度为 O(1) 的 原地 算法解决这个问 ...

  6. leetcode(189) 旋转数组

    **给定一个数组,将数组中的元素向右移动 k 个位置,其中 k 是非负数. 进阶: 尽可能想出更多的解决方案,至少有三种不同的方法可以解决这个问题. 你可以使用空间复杂度为 O(1) 的 原地 算法解 ...

  7. leetcode 189. 旋转数组

    题目 思路 先左边翻转,再右边翻转,最后整体翻转. 注意存在翻转超过一个周期的情况,要先取余,避免越界. 题解 class Solution {public void rotate(int[] num ...

  8. [刷题]leetcode\189_轮转数组

    三次反转 1.整体反转 2.前半部分反转 3.后半部分反转 tips:python库函数list.reverse()会报错,需要自己实现. class Solution:def rotate(self ...

  9. python轮转数组及nums和nums[:]的区别

    文章目录 189. 轮转数组 nums和nums[:] python数组两元素互换其值 a=[None] * n创建列表 异或^: 本文主要利用leetcode上的189. 轮转数组来解剖其涉及到的a ...

最新文章

  1. Attention机制总结 看明白了的
  2. 开源的linux网关untangle
  3. 如何使用 Druid 和 Kafka 构造 Kappa 架构完成流量分析
  4. Python爬虫入门教程 21-100 网易云课堂课程数据抓取
  5. python分支结构使用if保留字吗_关于Python分支结构,以下选项中描述不正确的是...
  6. Algorithm I assignment Collinear
  7. Qt保存日志调试信息输出文件
  8. 并发编程面试题(2020最新版)
  9. 互联网公司怪相:一边裁员,一边忙着做慈善
  10. 利用最小二乘法进行参数估计
  11. 【计算机毕业设计】017学生公寓电费信息管理系统
  12. 协作乐高 All In One:DAO工具大全
  13. 【艾琪出品】《计算机应用基础》【试题汇总1】
  14. R语言爬取豆瓣图书Top250
  15. Oracle 体系结构(8)—— Oracle 的审计文件(Audit files)
  16. java下载pdf_java – 下载时空白PDF
  17. AE基础教程(17)——第17章 父级
  18. 制作 Windows8 to Go
  19. 松下PLC控制松下伺服电机(上位机发送控制命令)
  20. python语音建模_该系统实现了基于深度框架的语音识别中的声学模型和语言模型建模...

热门文章

  1. 深入分析基于Micrometer和Prometheus实现度量和监控的方案
  2. 蓝桥杯——基础练习——十六进制转十进制
  3. crm呼叫中心(CRM系统中呼叫中心的作用)
  4. 电脑调分辨率黑屏了怎么办_Win7系统屏幕分辨率调高了就出现黑屏如何解决
  5. 导线截面积与载电流的计算
  6. 霍金的博士毕业论文,你拜读过了吗?
  7. 服务器BMC知识介绍
  8. DOTA作弊地址,持续更新
  9. url中设置mysql时区为东八区(即北京时间)
  10. Django web框架学习之旅(4)