题目及测试用例
package pid189;
/*旋转数组
给定一个数组,将数组中的元素向右移动 k 个位置,其中 k 是非负数。
示例 1:
输入: [1,2,3,4,5,6,7] 和 k = 3
输出: [5,6,7,1,2,3,4]
解释:
向右旋转 1 步: [7,1,2,3,4,5,6]
向右旋转 2 步: [6,7,1,2,3,4,5]
向右旋转 3 步: [5,6,7,1,2,3,4]
示例 2:
输入: [-1,-100,3,99] 和 k = 2
输出: [3,99,-1,-100]
解释:
向右旋转 1 步: [99,-1,-100,3]
向右旋转 2 步: [3,99,-1,-100]
说明:
尽可能想出更多的解决方案,至少有三种不同的方法可以解决这个问题。
要求使用空间复杂度为 O(1) 的原地算法。*/
public class main
{
public static void main(String[] args) {
int[][] testTable = {{1,2,3,4,5,6,7},{-1,-100,3,99},{-1,-100,3,99},{4,6,2,0,-99}};
int[] testTable2={3,2,3,6};
/*for (int[] ito : testTable) {
test(ito);
}*/
for(int i=0;i<4;i++){
test(testTable[i],testTable2[i]);
}
}
private static void test(int[] ito,int ito2) {
Solution solution = new Solution();
int rtn;
long begin = System.currentTimeMillis();
for (int i = 0; i < ito.length; i++) {
System.out.print(ito[i]+" ");
}
System.out.println(ito2);
System.out.println();
//开始时打印数组
//rtn =
solution.rotate(ito,ito2);//执行程序
long end = System.currentTimeMillis();
//System.out.println(ito + ": rtn=" + rtn);
//System.out.println(ito + ": rtn=" +rtn);
for (int i = 0; i < ito.length; i++) {
System.out.print(ito[i]+" ");
}//打印结果几数组
System.out.println();
System.out.println("耗时:" + (end - begin) + "ms");
System.out.println("-------------------");
}
}
方法1(33个用例成功,一个超时,速度不够快) 是o(kn)
package pid189;
public class Solution
{
//第一种 一次一个向右移动1位 循环一圈 总共循环k次
public void rotate(int[] nums, int k) {
int length=nums.length;
int tempPrev;
int tempNext;
k=k%length;
if (k==0&&length==0&&length==1)
{
return;
}
for(int i=0;i<k;i++){
// 1 1 3 4
tempNext=nums[1];
tempPrev=nums[0];
for(int j=0;j<length-1;j++){
nums[j+1]=tempPrev;
tempPrev=tempNext;
tempNext=nums[(j+2)%length];
}
nums[0]=tempPrev;
}
}
}
以下为别人的方法
一:使用临时空间。
public class Solution {
public void rotate(int[] nums, int k) {
k = k % nums.length;
if (k == 0) return;
int[] buf = new int[k];
for(int i=0; i<k; i++) buf[i] = nums[nums.length-k+i];
for(int i=nums.length-1; i>=k; i--) nums[i] = nums[i-k];
for(int i=0; i<k; i++) nums[i] = buf[i];
}
}
方法二:逐个向前推移,直到所有元素都在目标位置。
public class Solution {
private int gcd(int a, int b) {
if (a < b) {
int t = a;
a = b;
b = t;
}
while (b > 0) {
int t = a % b;
a = b;
b = t;
}
return a;
}
public void rotate(int[] nums, int k) {
k = k % nums.length;
int g = gcd(nums.length, k);
int l = nums.length * k / g;
for(int i=0; i<g; i++) {
int last = nums[(i+k)%nums.length];
for(int j=0; j<l; j+=k) {
int next = nums[(i+j+k)%nums.length];
nums[(i+j+k)%nums.length] = last;
last = next;
}
nums[(i+k)%nums.length] = last;
}
}
}
方法三:翻转。
public class Solution {
private void reverse(int[] nums, int from, int to) {
while (from < to) {
nums[from] ^= nums[to];
nums[to] ^= nums[from];
nums[from] ^= nums[to];
from ++;
to --;
}
}
public void rotate(int[] nums, int k) {
k = k % nums.length;
reverse(nums, 0, nums.length-k-1);
reverse(nums, nums.length-k, nums.length-1);
reverse(nums, 0, nums.length-1);
}