2010计算机考研题:循环左移数组

[img]http://dl.iteye.com/upload/attachment/0078/1047/63b64c14-c18b-30f6-9c90-da37799a9c6c.jpg[/img]

一、第一种方法,都想得到的。
static int[] LeftShift1(int[] arr,int K){//K为循环左移位数  
int N=arr.length;
int[] new_arr=new int[N]; //新开一个数组,空间复杂度O(n)
for(int i = 0; i <N; i++)
new_arr[i] = arr[(K+i)%N ];
return new_arr;
}



二、利用“翻转”完成优化,《编程之美》上的算法

  考虑一下数组A中元素1234567循环左移2位到底是怎么个情况!!!将数组A分成两个部分:A[0~k-1] 和 A[k~n-1] ,(12与34567)将这两个部分分别翻转,然后放在一起在翻转(逆序)。具体是这样的:

(1)翻转12:12 ---> 21

(2)翻转34567: 34567 ---> 76543

(3)一起翻转2176543:2176543 --->3456712


//翻转b~e
static void Reverse(int[] arr, int b, int e){
while(b < e){
int temp = arr[e]; //只需新开一个辅助空间
arr[e] = arr[b];
arr[b] = temp;
b++;
e--;
}
}

//左移K位
static void LeftShift(int[] arr, int K){
int N=arr.length;

//如果K>N,取K=K%N。

K %= N;
Reverse(arr, 0, K - 1);
Reverse(arr, K, N - 1);
Reverse(arr, 0, N - 1);
}


第一种算法有O(n)的空间复杂度,第二种有O(1)的空间复杂度,两种算法时间复杂度同为O(n)。

测试程序:

public class Test{

//方法一
static int[] LeftShift1(int[] arr,int K){//K为循环左移位数
int N=arr.length;
int[] new_arr=new int[N];
for(int i = 0; i <N; i++)
new_arr[i] = arr[(K+i)%N ];
return new_arr;
}

static void print(int[] arr){
for(int i=0;i<arr.length;i++)
System.out.print(arr[i]+" ");
System.out.println();
}

//翻转b~e
static void Reverse(int[] arr, int b, int e){
while(b < e){
int temp = arr[e];
arr[e] = arr[b];
arr[b] = temp;
b++;
e--;
}
}

//方法二
static void LeftShift(int[] arr, int K){
int N=arr.length;
K %= N;
Reverse(arr, 0, K - 1);
Reverse(arr, K, N - 1);
Reverse(arr, 0, N - 1);
}

public static void main(String[] args){
int[] a={1,2,3,4,5,6,7};
print(a);
int[] new_arr = LeftShift1(a,2);
print(new_arr);

// Reverse(a,2,5);
LeftShift(a, 4);
print(a);
}
}



运行:
C:\ex>java Test
1 2 3 4 5 6 7
3 4 5 6 7 1 2
5 6 7 1 2 3 4
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值