原题地址:https://leetcode-cn.com/problems/rotate-array/description/

给定一个数组,将数组中的元素向右移动 个位置,其中 是非负数。

示例 1:

输入: [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:

输入: [-1,-100,3,99] 和 k = 2
输出: [3,99,-1,-100]
解释:
向右旋转 1 步: [99,-1,-100,3]
向右旋转 2 步: [3,99,-1,-100]

说明:

  • 尽可能想出更多的解决方案,至少有三种不同的方法可以解决这个问题。
  • 要求使用空间复杂度为 O(1) 的原地算法。

以上是原题


这道算法题目本身并不难,但要求使用三种不同方法解决问题,这就考验小伙伴们脑洞能开多大了。。。

解法一:

  首先用最普通的解法,根据题目描述,我们不难得出,将一个元素右移k个位置,原处于index位置的元素会出现在index + k 的位置上,如果index + k 超出数组长度,那么从0开始接着移动,新的下标等价于 (index + k) % length.

  直接上代码:

    //旋转数组
public void rotate(int[] nums, int k) {
int[] temp = Arrays.copyOf(nums, nums.length);
for (int index = 0; index < temp.length; index++) {
nums[(index + k) % temp.length] = temp[index];
}
}

  这种解法简单粗暴,效率也不错,但其实题目中要求尽量使用空间复杂度为O(1)的原地算法,上述解法使用了一个与输入数组同样大小的空间。

解法二:

  移动第一个元素到k位置,将原本处在k位置的元素向右移动k位置,如果遇到了超出数组长度且指针指向数组第0个位置时,指针后移一位。

  

     public void rotate(int[] nums, int k) {
if (nums.length == 0 || (k %= nums.length) == 0) {
return;
}
int length = nums.length;
int start = 0, index = 0, cnt = 0, temp = 0;
int cur = nums[index];
while (cnt++ < length) {
index = (index + k) % length;
temp = nums[index];
nums[index] = cur;
if (index == start) { //是否循环到已处理过的元素
++start;
cur = nums[++index];
} else {
cur = temp;
}
}
}

  执行该方法时,数组状态变化如下:

  测试数据: [2, 7, 11, 15, 12, 16]   向右移动2位

  2   7     15  12  16    
  2   7   2  15    16    
    7   2  15  11  16    
  12  7   2     11  16
  12  7   2  7   11  
  12    2  7   11  15

解法三:

  这种方法比较特别,将原有数组用 length - k 分割为两段,分别对这两段中的数字进行首尾换位,然后再对整个数组进行首尾换位。

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

  同样给出数据状态:

  测试数据: [2, 7, 11, 15, 12, 16]   向右移动2位

  15  11  7   2  12  16    //第一次reverse
  15  11  7   2  16  12    //第二次reverse
  12  16  2   7  11  15    //第三次reverse

  坦白说,这个方法我没想明白什么原理,但的确很神奇,如果有朋友明白里的原理,还请不吝赐教啊。。。。。

旋转数组 [ LeetCode ]的更多相关文章

  1. [LeetCode] Rotate Array 旋转数组

    Rotate an array of n elements to the right by k steps. For example, with n = 7 and k = 3, the array  ...

  2. LeetCode 189. Rotate Array (旋转数组)

    Rotate an array of n elements to the right by k steps. For example, with n = 7 and k = 3, the array  ...

  3. 【Leetcode】【简单】【189. 旋转数组】【JavaScript】

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

  4. LeetCode初级算法--数组02:旋转数组

    LeetCode初级算法--数组02:旋转数组 搜索微信公众号:'AI-ming3526'或者'计算机视觉这件小事' 获取更多算法.机器学习干货 csdn:https://blog.csdn.net/ ...

  5. [LeetCode] 189. Rotate Array 旋转数组

    Given an array, rotate the array to the right by k steps, where k is non-negative. Example 1: Input: ...

  6. 前端与算法 leetcode 189. 旋转数组

    目录 # 前端与算法 leetcode 189. 旋转数组 题目描述 概要 提示 解析 算法 # 前端与算法 leetcode 189. 旋转数组 题目描述 189. 旋转数组 概要 把他当做一到简单 ...

  7. LeetCode 189. 旋转数组(Rotate Array)

    189. 旋转数组 LeetCode189. Rotate Array 题目描述 给定一个数组,将数组中的元素向右移动 k 个位置,其中 k 是非负数. 示例 1: 输入: [1,2,3,4,5,6, ...

  8. 【LeetCode每天一题】Search in Rotated Sorted Array(在旋转数组中搜索)

    Suppose an array sorted in ascending order is rotated at some pivot unknown to you beforehand.(i.e., ...

  9. Leetcode 153.寻找旋转数组中的最小值

    寻找旋转数组中的最小值 假设按照升序排序的数组在预先未知的某个点上进行了旋转. ( 例如,数组 [0,1,2,4,5,6,7] 可能变为 [4,5,6,7,0,1,2] ). 请找出其中最小的元素. ...

随机推荐

  1. 数字滤波器的MATLAB与FPGA实现--Altera/Verilog版的pdf版,杜勇等编著的书。

    自己在网上找了很久才找到的资源,花了很大的劲,觉得不易,特地分享给大家.本书讲了使用FPGA的Fir IIR IP核与Matlab配合使用生成滤波器的详细使用方法.贴出地址,http://downlo ...

  2. UVa Problem 100 The 3n+1 problem (3n+1 问题)

    参考:https://blog.csdn.net/metaphysis/article/details/6431937 #include <iostream> #include <c ...

  3. C++ vector二维数组

    C++ 构建二维动态数组 int **p; p = ]; //注意,int*[10]表示一个有10个元素的指针数组 ; i < ; ++i) { p[i] = ]; } 这样就构成10*5的数组 ...

  4. Django的命令操作,python

    忘记时候,查看命令用:python manage.py 1 建立项目的命令: django-admin.py startproject project_name 2 在项目的目录下建立app: dja ...

  5. mac 安装php redis扩展

    git clone git://github.com/nicolasff/phpredis.git cd ./phpredis phpize 如果报 Cannot find autoconf. Ple ...

  6. cachel-control

    nodejs: res.set('Cache-Control', 'public, max-age=31557600'); express全局设置:       app.use(express.sta ...

  7. JavaScript RegExp 身份证、账号密码、email正则

    什么是正则表达式 正则表达式是构成搜索模式. 在文本中搜索数据时,可以使用此搜索模式来描述正在搜索的内容. 正则表达式可以是单个字符,也可以是更复杂的模式. 正则表达式可用于执行所有类型的文本搜索和文 ...

  8. 在阿里云上遇见更好的Oracle(四)

    2016.5.13,北京,第七届数据库技术大会. 从最初的itpub社区,到后来被it168收购,DBA社区的线下聚会发展成2010年第一届数据库技术大会(DTCC).第一届大会汇聚了社区内活跃的各位 ...

  9. DP入门(3)——多阶段决策问题

    多阶段决策问题,简单地说,每做一次决策就可以得到解的一部分,当所有决策做完之后,完整的解就“浮出水面”了.在回溯法中,每次决策对应于给一个结点产生新的子树,而解的生成过程对应一棵解答树,结点的层数就是 ...

  10. 前端JQuery中获取一个div下的多个id值

    获取所有的Id值,方法是通过div.class获取全局的值,然后再提取具体的Id值 方法一:用for循环,因为$("div.class")获取的是一个数组,通过循环读取出数组中的每 ...