力扣----轮转数组

题目链接:189. 轮转数组 - 力扣(LeetCode)

思路一

我们可以在进行每次轮转的时候,先将数组的最后一个数据的值存储起来,接着将数组中前n-1个数据依次向后移,最后将存储起来的值赋给数组中的第一个数据。

先将数组中最后的一个元素的值存到变量tmp中,如下图

接着将数组中前n-1个数据依次向后移,如下图

最后再将tmp中的值赋值给nums[0],如下图

以上图是表示一次轮转的,如果还要轮转,重复上面的操作。

代码实现

java 复制代码
public void rotate(int[] nums, int k) {
        for(int i=0;i<k;i++){
            int tmp=nums[nums.length-1];
            //将前n-1个元素向后移
            for(int j=nums.length-1;j>0;j--){
                nums[j]=nums[j-1];
            }
            nums[0]=tmp;
        }
    }

当我们提交以上代码时,会发现不成功。

思路是对的,但是上面代码时间复杂度为O(kn),太复杂了,超出了题目的时间限制。

思路二

造成思路一时间复杂度太大的原因是: 思路一中有两个循环,一个循环是数组右旋的次数,另一个循环要将数组中的元素全部遍历一遍,这样当右旋次数足够多,数组中的元素很多时,效率就很低了。

思路二是k次旋转法。

下面以旋转次数为3来讲解,也就是k=3

先将数组全部旋转一遍,如下图

再以下标为0为起始点和下标为(k%nums.length)-1为终点来旋转,如下图

最后以下标为(K%数组长度)为起始点和以下标为(数组长度-1)为终点来旋转数组。

这样就完成了数组的3次右旋。

代码实现

java 复制代码
public void reverse(int[] nums,int start,int end){
        while(start<end){
            int tmp=nums[start];
            nums[start]=nums[end];
            nums[end]=tmp;
            start++;
            end--;
        }
    }
    public void rotate(int[] nums, int k) {
        reverse(nums,0,nums.length-1);
        reverse(nums,0,(k%nums.length)-1);
        reverse(nums,k%nums.length,nums.length-1);
    }

思路三

我们可以创建一个新的数组,将原数组中的数据按照数组旋转之后的的位置放置到新数组中对应的位置。最后我们再将新数组复制到原数组中就行了。

有一个公式:((i+k)%数组的长度) 的值 是 原数组中下标为i的数据 在 新数组中的位置。

其中i为原数组中数据的小标,k为旋转次数。

理解公式:

假如数组向右旋转k,也就是让数组中的数据向右移动k个位置,但是如果k大于数组长度,就会越界,所以我们要%数组的长度。因为如果旋转的次数超过数组的长度,也就是旋转k次的效果和k减去数组的长度次的效果是一样的。

代码实现

java 复制代码
public void rotate(int[] nums, int k) {
        int n=nums.length;
        //创建一个新数组jian
        int[] newNums=new int[n];
        //将原数组中的数据放到新数组中
        for(int i=0;i<n;i++){
            newNums[(i+k)%n]=nums[i];
        }
        //将新数组复制到原数组
        System.arraycopy(newNums,0,nums,0,n);
    }
相关推荐
melck7 分钟前
liunx日志查询常用命令总结
java·服务器·网络
SweetCode9 分钟前
裴蜀定理:整数解的奥秘
数据结构·python·线性代数·算法·机器学习
守护者17012 分钟前
JAVA学习-练习试用Java实现“实现一个Hadoop程序,使用Hive进行复杂查询和数据筛查”
java·学习
程序员 小柴18 分钟前
docker的与使用
java·docker·eureka
ゞ 正在缓冲99%…23 分钟前
leetcode76.最小覆盖子串
java·算法·leetcode·字符串·双指针·滑动窗口
xuanjiong23 分钟前
纯个人整理,蓝桥杯使用的算法模板day2(0-1背包问题),手打个人理解注释,超全面,且均已验证成功(附带详细手写“模拟流程图”,全网首个
算法·蓝桥杯·动态规划
Seven9737 分钟前
【Guava】并发编程ListenableFuture&Service
java
WannaRunning37 分钟前
浅谈Tomcat数据源连接池
java·oracle·tomcat
惊鸿.Jh42 分钟前
【滑动窗口】3254. 长度为 K 的子数组的能量值 I
数据结构·算法·leetcode
明灯L43 分钟前
《函数基础与内存机制深度剖析:从 return 语句到各类经典编程题详解》
经验分享·python·算法·链表·经典例题