Rotate Array
来源:互联网 发布:网络电视调试 编辑:程序博客网 时间:2024/06/15 21:46
Leetcode中的array的rotate问题
Leetcode当中有一系列的题目是关于array的,而关于array的问题中又有一些题目是关于array的“rotate”的操作的。准备写一个关于rotate的专题,将关于rotate的问题整理一下。
闲言少叙,我们直接来看第一题。
https://leetcode.com/problems/rotate-array/
原题
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].
Hint:
Could you do it in-place with O(1) extra space?
翻译:将长度为n的数组向右旋转k步,比如n=7,k=3,那么数组 [1,2,3,4,5,6,7] 被旋转成[5,6,7,1,2,3,4]。
提示:
你能在O(1)的额外空间中解决这个问题吗。
问题分析
看到这个问题的基本想法就是每次rotate一步,然后将rotate进行k次就OK了,O(1)也没有什么问题,但是很显然时间复杂度达到O(kn),效率太低啦。其实接下来想的问题就是是否可以仅仅使用swap操作,将元素和他应该到的位置进行swap。
[1,2,3,4,5,6,7] 被旋转成[5,6,7,1,2,3,4],我将1放到4的位置,4放到7的位置,7放到3的位置,3放到6的位置,6放到2的位置,2放到5的位置,最后5放到1的位置,每次我只要计算出这个被替换掉的元素下一次应该到的位置就行了!看似很完美,额外空间复杂度O(1)。
实现了一下发现一个问题,只有k%n和n互质的时候,这个方法才有效!
比如数组为[1,2,3,4],k=2。第一次1换到3,然后3换到1,到了初始位置了,结束,但是数组为[3,2,1,4]。当n和k%n有公因子的时候,就会出现这种问题。这个问题可以这样解决,找到n和k%n的最大公因子c,然后对数组的前c个数进行上述的迭代替换操作。这种方法的时间复杂度是O(n)。
贴上代码供大家参考:
public void rotate(int[] nums, int k) { if(nums.length == 0) return; k = k%nums.length; if(k < 1) return; int gcd = divisor(nums.length,k); for(int i = 0; i < gcd; i++) { int temp = nums[i]; int tempIndex = i; while((tempIndex + k)%nums.length != i) { int theTemp = nums[(tempIndex + k)%nums.length]; nums[(tempIndex + k)%nums.length] = temp; temp = theTemp; tempIndex = (tempIndex + k)%nums.length; } nums[i] = temp; } return;}int divisor(int m,int n){ int temp; while(m%n!=0){ temp=n; n=m%n; m=temp; } return n; }
当然咯,网上通用的做法是先reverse整个数组,然后对前k个和后面n-k个进行reverse,想法很好,但是值得注意的是相比我的方法,该方法可以让每个元素替换两次才到位的哟,其实它的时间复杂度是O(2n),但是这个方法省却了最大公约数的计算,也贴上代码供大家参考。
public void rotate(int[] nums, int k) { if(nums.length == 0) { return; } k = k%nums.length; reverse(nums,0,nums.length - 1); reverse(nums,0, k - 1); reverse(nums,k,nums.length - 1); return;}public void reverse(int[] nums, int head, int end){ int temp; while(end > head) { temp = nums[end]; nums[end] = nums[head]; nums[head] = temp; ++head; --end; } return;}
接下来,我们何妨看看链表的rotate操作,哈哈~~~
- Rotate Array
- Rotate Array
- Rotate Array
- Rotate Array
- Rotate Array
- Rotate Array
- rotate array
- Rotate Array
- Rotate Array
- Rotate Array
- Rotate Array
- Rotate Array
- Rotate Array
- Rotate Array
- Rotate Array
- Rotate Array
- Rotate Array
- Rotate Array
- 运算符笔记
- 机器学习中的数学(1):回归、梯度下降
- This Handler class should be static or leaks might occur Android警告处理
- Selenium学习笔记之010:层级定位
- Python进阶---python pass用法
- Rotate Array
- java中获取另一个线程中的信息
- 机器学习中的数学(2):线性回归、偏差、方差权衡
- QListWidget常用方法
- 最全前端面试问题及答案总结 - trigkit4
- Android中的动态加载机制
- Centos7更改yum源步骤(转)
- java 数据库连接MySQL
- letting go ,偶然间的发现