旋转数组 [ LeetCode ]
原题地址:https://leetcode-cn.com/problems/rotate-array/description/
给定一个数组,将数组中的元素向右移动 k 个位置,其中 k 是非负数。
示例 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 ]的更多相关文章
- [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 ...
- 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 ...
- 【Leetcode】【简单】【189. 旋转数组】【JavaScript】
189. 旋转数组 给定一个数组,将数组中的元素向右移动 k 个位置,其中 k 是非负数. 示例 1: 输入: [1,2,3,4,5,6,7] 和 k = 3输出: [5,6,7,1,2,3,4]解释 ...
- LeetCode初级算法--数组02:旋转数组
LeetCode初级算法--数组02:旋转数组 搜索微信公众号:'AI-ming3526'或者'计算机视觉这件小事' 获取更多算法.机器学习干货 csdn:https://blog.csdn.net/ ...
- [LeetCode] 189. Rotate Array 旋转数组
Given an array, rotate the array to the right by k steps, where k is non-negative. Example 1: Input: ...
- 前端与算法 leetcode 189. 旋转数组
目录 # 前端与算法 leetcode 189. 旋转数组 题目描述 概要 提示 解析 算法 # 前端与算法 leetcode 189. 旋转数组 题目描述 189. 旋转数组 概要 把他当做一到简单 ...
- LeetCode 189. 旋转数组(Rotate Array)
189. 旋转数组 LeetCode189. Rotate Array 题目描述 给定一个数组,将数组中的元素向右移动 k 个位置,其中 k 是非负数. 示例 1: 输入: [1,2,3,4,5,6, ...
- 【LeetCode每天一题】Search in Rotated Sorted Array(在旋转数组中搜索)
Suppose an array sorted in ascending order is rotated at some pivot unknown to you beforehand.(i.e., ...
- Leetcode 153.寻找旋转数组中的最小值
寻找旋转数组中的最小值 假设按照升序排序的数组在预先未知的某个点上进行了旋转. ( 例如,数组 [0,1,2,4,5,6,7] 可能变为 [4,5,6,7,0,1,2] ). 请找出其中最小的元素. ...
随机推荐
- javascript 之 为函数设置默认参数值
方法一: function example(a,b){ var a = arguments[0] ? arguments[0] : 1;//设置参数a默认为1 var b = arguments[1] ...
- vue2.0 Axios 的简单用法
安装 使用 npm: $ npm install axios 使用 bower: $ bower install axios 使用 cdn: <script src="https:// ...
- python基础之socket套接字基础part2
基于UDP的socket 面向无连接的不可靠数据传输,可以没有服务器端,只不过没有服务器端,发送的数据会被直接丢弃,并不能到达服务器端 1 #客户端 2 import socket 3 ip_port ...
- WPF中的命令与命令绑定(二)
原文:WPF中的命令与命令绑定(二) WPF中的命令与命令绑定(二) 周银辉在WPF中,命令(Commandi ...
- 浅析 Linux 初始化 init 系统,Systemd
原文地址:http://www.ibm.com/developerworks/cn/linux/1407_liuming_init3/ Systemd 的简介和特点 Systemd 是 Linux 系 ...
- 三张照片解决--win10系统的edge浏览器设置为浏览器IE8,IE7,IE9---完美解决 费元星
主要思想: 第二种方法: 参考文档: 1.可以在系统盘的C:\Program Files\Internet Explorer中找到iexplore.exe,然后将其发送到桌 ...
- 『JavaScript』封装
封装可以被定义为对对象的内部数据表现形式和实现细节进行隐藏.通过封装可以强制实施信息隐藏. 在JavaScript中,并没有显示的声明私有成员的关键字等.所以要想实现封装/信息隐藏就需要从另外的思路出 ...
- 云计算之路-阿里云上:原来“黑色0.1秒”发生在socket读取数据时
在昨天的博文(云计算之路-阿里云上:读取缓存时的“黑色0.1秒”)中我们犯了一个很低级的错误——把13ms算成了130ms(感谢陈硕发现这个错误!),从而对问题的原因作出了错误的推断,望大家谅解! 从 ...
- 第二十四篇configparser(**)
configparser模块 config:配置,parser:解析.字面意思理解configparser模块就是配置文件的解析模块. 来看一个好多软件的常见文档格式如下: [DEFAULT] # 标 ...
- java 读取配置文件 与更新
笔记 public class Config { private static Properties props = new Properties(); static File configFile ...