博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
[LeetCode] Rotate Array 旋转数组
阅读量:7106 次
发布时间:2019-06-28

本文共 2763 字,大约阅读时间需要 9 分钟。

 

Rotate an array of n elements to the right by k steps.

For example, with n = 7 and k = 3, the array [1,2,3,4,5,6,7] is rotated to [5,6,7,1,2,3,4].

Note:

Try to come up as many solutions as you can, there are at least 3 different ways to solve this problem.

Hint:
Could you do it in-place with O(1) extra space?

Credits:

Special thanks to  for adding this problem and creating all test cases.

 

新题抢先刷,这道题标为Easy,应该不是很难,我们先来看一种O(n)的空间复杂度的方法,我们复制一个和nums一样的数组,然后利用映射关系i -> (i+k)%n来交换数字。代码如下:

 

解法一:

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

 

由于提示中要求我们空间复杂度为O(1),所以我们不能用辅助数组,上面的思想还是可以使用的,但是写法就复杂的多,而且需要用到很多的辅助变量,我们用题目中的例子来展示下面这种算法的nums的变化过程:

1 2 3 4 5 6 7

1 2 3 1 5 6 7
1 2 3 1 5 6 4
1 2 7 1 5 6 4
1 2 7 1 5 3 4
1 6 7 1 5 3 4
1 6 7 1 2 3 4
5 6 7 1 2 3 4

 

解法二:

class Solution {public:    void rotate(vector
& nums, int k) { if (nums.empty() || (k %= nums.size()) == 0) return; int n = nums.size(), start = 0, i = 0, cur = nums[i], cnt = 0; while (cnt++ < n) { i = (i + k) % n; int t = nums[i]; nums[i] = cur; if (i == start) { ++start; ++i; cur = nums[i]; } else { cur = t; } } }};

 

根据热心网友的留言,这道题其实还有种类似翻转字符的方法,思路是先把前n-k个数字翻转一下,再把后k个数字翻转一下,最后再把整个数组翻转一下:

1 2 3 4 5 6 7

4 3 2 1 5 6 7
4 3 2 1 7 6 5
5 6 7 1 2 3 4

 

解法三:

class Solution {public:    void rotate(vector
& nums, int k) { if (nums.empty() || (k %= nums.size()) == 0) return; int n = nums.size(); reverse(nums.begin(), nums.begin() + n - k); reverse(nums.begin() + n - k, nums.end()); reverse(nums.begin(), nums.end()); }};

 

由于旋转数组的操作也可以看做从数组的末尾取k个数组放入数组的开头,所以我们用STL的push_back和erase可以很容易的实现这些操作。

 

解法四:

class Solution {public:    void rotate(vector
& nums, int k) { if (nums.empty() || (k %= nums.size()) == 0) return; int n = nums.size(); for (int i = 0; i < n - k; ++i) { nums.push_back(nums[0]); nums.erase(nums.begin()); } }};

 

下面这种方法其实还蛮独特的,通过不停的交换某两个数字的位置来实现旋转,根据的思路改写而来,数组改变过程如下:

1 2 3 4 5 6 7

5 2 3 4 1 6 7
5 6 3 4 1 2 7
5 6 7 4 1 2 3
5 6 7 1 4 2 3
5 6 7 1 2 4 3
5 6 7 1 2 3 4

 

解法五:

class Solution {public:    void rotate(vector
& nums, int k) { if (nums.empty()) return; int n = nums.size(), start = 0; while (n && (k %= n)) { for (int i = 0; i < k; ++i) { swap(nums[i + start], nums[n - k + i + start]); } n -= k; start += k; } }};

 

参考资料:

 

转载地址:http://xaphl.baihongyu.com/

你可能感兴趣的文章
UIScrollView实现图片循环滚动
查看>>
我的友情链接
查看>>
王垠:怎样写一个解释器
查看>>
解决unicodedecodeerror ascii codec can’t decode byte 0xd7 in position 9 ordinal not in range(128)...
查看>>
Redis和Memcached的区别
查看>>
CSS选择器种类及介绍
查看>>
struts2 + form 表单上传文件
查看>>
Centos7下安装mongodb
查看>>
ES架构及原理
查看>>
Windows7 自动更新时遇到故障
查看>>
我的友情链接
查看>>
spring加载配置属性文件(properties)
查看>>
redis设置
查看>>
android的唯一性
查看>>
深入理解java虚拟机——OutOfMemoryError异常
查看>>
《The way to go》中文版
查看>>
jQuery设置元素是否显示
查看>>
samsung Galaxy S3 i9300 获得root权限
查看>>
.NET EasyUI datebox添加清空功能
查看>>
查看Android手机保存的WIFI无线密码
查看>>