码迷,mamicode.com
首页 > 其他好文 > 详细

Rotate Array

时间:2017-08-31 22:19:55      阅读:232      评论:0      收藏:0      [点我收藏+]

标签:different   ble   esc   引入   reverse   ++i   void   方法   solution   

LeetCode 189  

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.

 

https://leetcode.com/problems/rotate-array/description/

 

方法一:借助额外空间

  借助额外空间来移动数组很简单,这种方法就不说了。

 

 

方法二:额外空间为0,只依靠交换

交换的最终目的是将位置为 i 的数字移动到 (i+k)%nums.size() 的位置,假设数组是1234567时,k = 3,则

1234567

5671234,

我们从0位置开始操作,将nums[0] 移动到 0+k 的位置,原来在0+k 位置的数字 num[0+k] 此时需要移动到下一个位置,也就是num[(0+k+k)%nums.size()]的位置,问题来了,如何做到这样的移动。 

我们引入三个变量来解释这个过程

storeposition——在交换之后用来存储位置被占的那个数字,也就是上述中的num[0+k]

currentposition——当前要移动的数字在数组中的初始位置

nextposition——当前要移动的数字的目的位置,同时也是下一个要移动的数字的位置

初始时storeposition= 0,currentposition = 0,nextposition = 0,k = 3

对照代码有以下过程:

                        storeposition  currentposition  nextposition  i   

  1  2  3  4  5  6  7      0        0        3    0

  4  2  3  1  5  6  7      0        3        6    1

  7  2  3  1  5  6  4      0        6        2    2

  3  2  7  1  5  6  4      0        2        5    3

  6  2  7  1  5  3  4      0        5        1    4

  2  6  7  1  5  3  4      0        1        4    5

  5  6  7  1  2  3  4      0        4        0    6 

 

若k可以被nums.size()整除,则k和nums.siz()的最小公倍数就是nums.size()本身,则当storeposition = nextposition时,只移动了整个过程的k/nums.size(),如k=2,nums= 123456,则第一圈移动完只移动了2/6,即整个过程的1/3.

再举一个例子 

                 s  c  n  i

1  2  3  4  5  6  0  0  2  0

3  2  1  4  5  6  0  2  4  1

5  2  1  4  3  6  0  4  0  2  //此时s = n = 0,说明位置为0,2,4的数字都已经到达了自身的最终位置,而n继续+k的话,并不会移动其他元素,因此此时需要将s+1,换一个“圈”

5  2  1  4  3  6  1    4  3  3  //s+=1,n=s+k, i++

5  4  1  2  3  6  1  3  5  4  

5  6  1  2  3  4  1  5  1  5  

 1 void swap(int * a, int * b)
 2 {
 3     *a = *a ^ *b;
 4     *b = *a ^ *b;
 5     *a = *a ^ *b;
 6 }
 7 void rotate(vector<int>& nums, int k) {
 8     if (nums.size() < 2 || k%nums.size() == 0) return; 
 9     k = k % nums.size();
10     int storeposition = 0,nextposition = k; //
11     for (unsigned i = 0; i < nums.size(); ++i)
12     {
13         swap(&nums[storeposition], &nums[nextposition]);
14         nextposition = (nextposition + k) % nums.size();
15         if (nextposition == storeposition)
16         {
17             ++i;
18             ++storeposition;
19             nextposition = (storeposition + k)%nums.size();
20         }
21     }
22 }

 

方法三:分解过程

  1234567 -->5671234的过程可以分解成以下过程:

  1234567-->7654321-->5674321-->5671234

  即反转三次,代码如下:

 1 void rotate(vector<int>& nums, int k)
 2 {
 3     k = k % nums.size();
 4     if (nums.size() < 2 || k == 0) return;
 5     vector<int>::iterator it = nums.begin();
 6     for (int i = 0; i < k; ++i) ++it;
 7     reverse(nums.begin(),nums.end());
 8     reverse(nums.begin(),it);
 9     reverse(it++,nums.end());
10 }

 

Rotate Array

标签:different   ble   esc   引入   reverse   ++i   void   方法   solution   

原文地址:http://www.cnblogs.com/qmdt/p/7460672.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!