原题地址: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. shell重温---基础篇(shell数组&数组操作)

    上篇博客已经分析重温了shell的运行方式以及其中的变量还有字符串,之后按照套路就是数组方面了,废话不多说,直接进入正题哈.(小白笔记,各位看官勿喷...)     bash shell呢,支持一位数 ...

  2. vue 项目如何使用微信分享接口

    首先做微信网页都要接入微信sdk: 安装sdk npm install weixin-js-sdk --save 具体可以查看微信公众平台技术文档:https://mp.weixin.qq.com/w ...

  3. FreeRTOS软件定时器的使用

    先贴上一个创建的代码,先声明一个句柄 TimerHandle_t pump_wakeup_timer_handle = NULL; 创建定时器和启动定时器,第三个参数,pdFALSE是只定时一次,pd ...

  4. jq 一个强悍的json格式化查看工具

    本文来自网易云社区 作者:娄超 在web 2.0时代json这种直观.灵活.高效数据格式基本已经成为一种标准格式,从各种web api,到配置文件,甚至现在连mysql都开始支持json作为数据类型. ...

  5. Ubuntu下使用Git_2

    接着上一篇的写,这里练习一下git clone 指令 指令格式 $ git clone <repository> <directory> <respository> ...

  6. C++学习012友元

    何为友元,我的理解,友元就是把另一个类当作是我的朋友,朋友之间,是可以访问一些私有的变量的. 所以,当我们将一个累声明为自己的友元类的时候,那么这个类就可以访问我们自己类中的某些私有变量等 当我把某个 ...

  7. SQL - SELECT COUNT用法

     SQL Server数据库  COUNT() 函数返回匹配指定条件的行数.   语法   SQL COUNT(column_name) 语法   COUNT(column_name) 函数返回指定列 ...

  8. Mac下安装pear库+phpDocumentor

    1. 首先安装pear: curl -o go-pear.php https://pear.php.net/go-pear.phar 看见这个就安装OK: % Total % Received % X ...

  9. Spring实战第九章学习笔记————保护Web应用

    保护Web应用 在这一章我们将使用切面技术来探索保护应用程序的方式.不过我们不必自己开发这些切面----我们将使用Spring Security,一种基于Spring AOP和Servlet规范的Fi ...

  10. Python第二天 (数据类型,变量 )

    1. 把任意数据类型赋值给变量 在Python中,等号=是赋值语句,可以把任意数据类型赋值给变量,同一个变量可以反复赋值,而且可以是不同类型的变量,例如: 例子:a = 123 # a是整数 prin ...