字符串循环左移
简介
给定一个字符串S[0…N-1],要求把S的前k个字符移动到S的尾部,如把字符串"abcdef"前面的两个字符’a’,'b’移动到字符串的尾部,得到新字符串"cdefab:即字符串循环左移k。
循环左移k位等价于循环右移n-k位。
算法要求:
- 时间复杂度为 O ( n ) O(n) O(n)
- 空间复杂度为 O ( 1 ) O(1) O(1)
问题分析
暴力位移法
- 每次循环左移1位,调用k次即可
- 时间复杂度 O ( k N ) O(kN) O(kN),时间复杂度为 O ( 1 ) O(1) O(1)
三次拷贝
- S[0…k] → \rightarrow → T[0…k]
- S[k+1…N-1] → \rightarrow → S[0…N-k-1]
- T[0…k] → \rightarrow → S[N-k…N-1]
- 时间复杂度 O ( N ) O(N) O(N),空间复杂度 O ( k ) O(k) O(k)
原地逆置
-
(
X
′
Y
′
)
′
=
Y
X
(X^{'}Y^{'})^{'} = YX
(X′Y′)′=YX
- 如:abcdef
- X = a b X=ab X=ab X ′ = b a X^{'}=ba X′=ba
- Y = c d e f Y=cdef Y=cdef Y ′ = f e d c Y^{'}=fedc Y′=fedc
- ( X ′ Y ′ ) ′ = ( b a f e d c ) ′ = f e d c b a (X^{'}Y^{'})^{'} = ({\color{red}{ba}}{\color{blue}{fedc}})^{'}={\color{blue}{fedc}}{\color{red}{ba}} (X′Y′)′=(bafedc)′=fedcba
- 时间复杂度 O ( N ) O(N) O(N),空间复杂度 O ( 1 ) O(1) O(1)
代码实现
/**
* 字符数组原地逆置
* @param str
* @param left
* @param right
* @return
*/
private char[] reverseString(char[] str, int left, int right) {
while (left < right) {
char t = str[left];
str[left++] = str[right];
str[right--] = t;
}
return str;
}
/**
*
* @param str
* @param k 循环左移k位
* @param len 字符数组总长度
* @return
*/
public char[] leftRotateString(char[] str, int k, int len) {
//防止左移位数超过数组总长度
k %= len;
str = reverseString(str, 0, k-1);
str = reverseString(str, k, len-1);
str = reverseString(str, 0, len-1);
return str;
}