题目描述:
定义字符串的左旋转操作:把字符串前面的若干个字符移动到字符串的尾部。
如把字符串abcdef左旋转2位得到字符串cdefab。
请实现字符串左旋转的函数,要求对长度为n的字符串操作的时间复杂度为O(n),空间复杂度为O(1)。
以下是我的答案,请指教,当然方法不只有这一种。
package left_shift;
/**
* @authorzhou shengshuai
*
*/
public class LeftShift {
public static final int GROUP_NUM = 3;
public void leftShift(String[] arr, intm) {
int len = arr.length;
/*
* A good comments from July:
* 大家开始可能会有这样的潜在假设,m < len。事实上,很多时候也的确是这样的。
* 但严格来说,我们不能用这样的“惯性思维”来思考问题,尤其在编程的时候,全面地考虑问题是很重要的。
* m可能是一个远大于len的整数,在这个时候,上面的解法是需要改进的。
* 右移m位之后的情形,跟右移m = m % len位之后的情形一样。
*/
m %= len;
int e = len % m;
int n = len / m;
for(int i = 0; i < n; i++) {
String tmp;
if (i == n - 1) {
while(e > 0) {
tmp = arr[len - e];
for(int j = 0; j < m; j++) {
arr[len - e - j] =arr[len - e - j - 1];
}
arr[len - e - m] = tmp;
--e;
}
} else
for(int j = 0; j < m; j++) {
tmp = arr[j];
arr[j] = arr[len - e - (1 + i) * m + j];
arr[len - e - (1 + i) * m + j] = tmp;
}
}
}
public void printArr(String[] arr) {
for(int i = 0; i < arr.length;i++) {
System.out.print(arr[i]);
}
System.out.println();
}
/**
* @param args
*/
public static void main(String[] args) {
String[] arr = { "a", "b", "c", "x","y","z", "e", "f", "g","h","i" };
LeftShift ls = newLeftShift();
ls.printArr(arr);
ls.leftShift(arr, GROUP_NUM);
ls.printArr(arr);
}
}
=============================================================================
时间复杂度分析(len为数组长度):
O((n-1)*m+e)
=O((len/m-1)*m+len%m)
=O(len)