问题为:
将一个n元一维向量向左旋转i个位置。例如,当n=8,i=3时候,向量x=abcdefgh,旋转为defghabc。如何用最少的时间和空间完成?
方案1 使用临时数组复制
此方法的过程为如下,缺点是需要一个大小为i的临时数组
- 将x的前i个元素复制到临时数组中
- 将余下的n-i个元素向左移动i个位置
- 将最初的i个元素从临时数组中复制到x中余下的位置
具体代码如下:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30public class Zuoxuan {
public static void main(String...args){
String x = "abcdefgh";
int i = 3;
String reString = doZuoxuan(x, i);
System.out.println(reString);
}
private static String doZuoxuan(String x, int i) {
//将x的前i个元素复制到临时数组中
char[] xChars = x.toCharArray();
char[] newTemp = new char[i];
for(int c=0; c<i; c++){
newTemp[c] = xChars[c];
}
//将余下的n-i个元素向左移动i个位置
for(int c=i; c<x.length(); c++){
xChars[c-i] = xChars[c];
}
//将最初的i个元素从临时数组中复制到x中余下的位置
for(int c=x.length()-i, j=0; c<x.length(); c++){
xChars[c] = newTemp[j++];
}
return String.valueOf(xChars);
}
}
方案2 构造左旋一位的函数
此方法如下,缺点是有过多的操作,运行时间长
- 定义一个函数,可以左旋一位
- 调用这个函数i次
具体代码如下:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30/* 定义一个函数,可以左旋一位
* 调用这个函数i次
*/
public class ZuoxuanOneByOne {
public static void main(String...args){
String x = "abcdefgh";
int i = 3;
for(int j=0; j<3; j++){
x = doZuoxuanOne(x);
}
System.out.println(x);
}
private static String doZuoxuanOne(String x) {
//将x的第一个元素复制到临时变量中
char[] xChars = x.toCharArray();
char tempChar = xChars[0];
//将余下的n-1个元素向左移动1个位置
for(int c=1; c<x.length(); c++){
xChars[c-1] = xChars[c];
}
//将第一个元素从临时变量中复制到x最后一位
xChars[x.length()-1] = tempChar;
return String.valueOf(xChars);
}
}
方案3 每隔i个元素跳跃移动
这个方法比较巧妙,很容易出错,步骤如下:
- 移动x[0]到临时变量t,然后移动x[i]到x[0],x[2i]到x[i]…以此类推(将所有下标对n取模),直至返回到取x[0]中的数据,此时改为从t取值然后终止过程
- 如果该过程没有置换全部元素,那再从x[1]开始~
- 一共置换gcd(n,i)次!!!n和i的最大公约数!
1 | //跳跃着移动 |
方案4 用翻转代替左旋
这是最巧妙最简单的一种方法,利用两次翻转,漂亮的完成了左旋。
- reverse(0,i-1); // cbadefgh
- reverse(i,n-1); // cbahgfed
- reverse(0,n-1); // defghabc
具体代码如下:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25//两次翻转
public class ZuoxuanFanzhuan {
public static void main(String...args){
String x = "abcdefgh";
int i = 3;
int n = x.length();
x = reverse(x, 0,i-1); // cbadefgh
x = reverse(x, i,n-1); // cbahgfed
x = reverse(x, 0,n-1); // defghabc
System.out.println(x);
}
//翻转x[l]~x[r]
private static String reverse(String x, int l, int r) {
char[] xChars = x.toCharArray();
int len = r-l+1;
char temp;
for(int i=l; i<l+len/2; i++){
temp = xChars[i];
xChars[i] = xChars[r-(i-l)];
xChars[r-(i-l)] = temp;
}
return String.valueOf(xChars);
}
}