个人第一道开始喽~ 上题!
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.
Could you do it in-place with O(1) extra space?
小侃:
起手我就没看懂题,啥叫rotate,啥是k,3有啥用,要是看到这个文章是因为看题没看懂的,请默默举起你的爪子~
后来明白了就是把最后一个数放第一个上去就叫一次rotate,e.g. :
原始:1234567, 一次rotate结果就是7123456, 两次rotate结果就是6712345. k就是这个rotate的次数。
顺便继续看,要求in-place with O(1), 这就是个坑爹要求,不让用多余的数组,给你一个数组你只能在这里面玩,好吧,你赢了。
这时候最容易想到的最笨的方法:一次rotate就一次循环喽(伪代码):
while(k!=0){
end = nums[length-1];
for(int j = 0; j< length-1;j++){
nums[j] = nums[j-1];
}
nums[0]=end;
k--;
}
不试不知道,那堆 test cases不是白给的,反正我写完了这玩意,然后看着没错,一点提交,屏幕赫然很多大字,大侠请重新来过,开玩笑啦,就是不让交,人家有效率要求,这算法超时。。好吧,你妹。。。再想办法。。
最后多方求证,小心推演,得到的理论如下, 我尽量解释,文学功底有限,凑合看~
原始:1234567,k=1变成7123456,k=2 变成6712345,k=3 变成 5671234,k=4 变成4567123。
说到底就是k等于几就把最后边几个数挪到最前面,后面的数保持先前的顺序,后面的数也保持先前顺序,那么我们接着想,拿k=3为例,5671234,所以有没有什么办法能一步就把567不管顺序的先拿到前面去,有,对调,1234567全数组对调(1换7,6换2,5换3)变成7654321,然后你就发现567在数组前面了,1234 在数组后面了,可惜顺序不对,不过没关系啦,1234567变7654321都做了,765变567和4321变1234不是小case,所以我们这道题就解出来了,不知道啥是最优解,至少递交成功啦。我的思路也就到这了,至少觉得面试出这个题我也能搞定他,不过不知道大神们还有啥更高端的办法>_< 。赶紧告诉我,也让我的智商开开光~
小解:
光吹牛不上代码的解析都是耍流氓~
public class Solution {
public void rotate(int[] nums, int k) {
k = (nums.length + (k % nums.length)) % nums.length;
int tmp;
reverse(nums,0,nums.length - 1);
reverse(nums,0,k-1);
reverse(nums,k,nums.length - 1);
}
public void reverse(int[] nums,int start,int end){
for (int i = start, j = end; i < j; i++, j--) {
int tmp = nums[i];
nums[i] = nums[j];
nums[j] = tmp;
}
}
}
希望我这些还算解释的清楚,如果大家要是有什么更好的方法,请告诉我,一起进步嘛。。至少让我进步嘛!