Rotate Array
题目要求向右旋转给定数组k次
Python代码:
class Solution(object):
def rotate(self, nums, k):
"""
:type nums: List[int]
:type k: int
:rtype: void Do not return anything, modify nums in-place instead.
"""
k = k % len(nums)
nums[:] = nums[-k:] + nums[:-k]
注意最后一定要nums[:] = nums[-k:] + nums[:-k]
而不是nums = nums[-k:] + nums[:-k]
因为在OJ中前者可以彻底改变旧数组,而后者只将他的引用改变到了一个新的数组中。
Solution中的几种解法:
1 Brute Force
暴力法,时间复杂度 O(n∗k) O ( n ∗ k ) 。
2 Using Extra Array
将数组按照轮转后的顺序排序在新数组中,再将新数组赋值到原数组中。
3 Using Cyclic Replacements
这是一个时间复杂度为
O(n)
O
(
n
)
的算法。算法的思想是从数组的第一个元素开始,直接将数组第一元素的数值替换到他轮转后的位置,同时将轮转后位置的原数值记录到temp中。如将1, 2, 3, 4, 5, 6, 7
这一序列轮转3次,即
k=3
k
=
3
。则直接将数组第一个位置nums[0]
的1
替换到nums[3]
的位置,同时将该位置原元素记录到temp中。所以替换后temp = 4
数组变为1, 2, 3, 1, 5, 6, 7
。第二次循环从nums[3]
位置开始,该位置原元素4
替换到他轮转后的位置并记录将被4
替换掉的元素的值到temp
中。循环n次后,数组全部被替换完毕。
将1, 2, 3, 4, 5, 6, 7
轮转三次:
1, 2, 3, 1, 5, 6, 7 temp=4
1, 2, 3, 1, 5 ,6 ,4 temp=7
1, 2, 7, 1, 5, 6, 4 temp=3
1, 2, 7 ,1, 5, 3, 4 temp=6
1, 6, 7, 1, 5, 3, 4 temp=2
1, 6, 7, 1, 2, 3, 4 temp=5
5, 6, 7, 1, 2, 3, 4
当
n/k
n
/
k
为整数时会要被替换的元素是我们第一次要替换元素的情况,如图:
所以我们通过两个循环解决问题。下面是leetcode中solution的Java代码:
public class Solution {
public void rotate(int[] nums, int k) {
k = k % nums.length;
int count = 0;
for (int start = 0; count < nums.length; start++) {//外部的循环,上图中的红色、绿色循环
int current = start;
int prev = nums[start];
do {
int next = (current + k) % nums.length;
int temp = nums[next];
nums[next] = prev;
prev = temp;
current = next;
count++;
} while (start != current);//内部的小循环,1,3,5元素间的相互替换
}
}
}
4 Using Reverse
先将整个数组反转,而后反转前k项,再反转后n-k项
Original List : 1 2 3 4 5 6 7
After reversing all numbers : 7 6 5 4 3 2 1
After reversing first k numbers : 5 6 7 4 3 2 1
After revering last n-k numbers : 5 6 7 1 2 3 4 --> Result