问题
给定一个字符串S[0...N−1]S[0...N−1],要求把SS的前个字符串移动到SS的尾部,如把字符串,前面的两个字符aa、移动到移动到字符串的尾部,得到新字符串cdefabcdefab:即字符串循环左移kk个:
- 循环左移2和kk2的效果相同;
- 循环左移位等价于循环右移n−kn−k位。
算法要求
- 时间复杂度为O(n)O(n),空间复杂度为O(1)O(1)
分析
- 暴力移位法
- 每次循环左移一位,调用kk次即可
- 时间复杂度为,空间复杂度为O(1)
- 三次拷贝法
- S[0...k]S[0...k] -> T[0...k]T[0...k]
- S[k+1...N−1]S[k+1...N−1] -> S[0...N−k−1]S[0...N−k−1]
- T[0...k]T[0...k] -> S[N−k...N−1]S[N−k...N−1]
- 时间复杂度O(N)O(N),空间复杂度O(k)O(k)
- 转置法
- (X’Y’)’ = YX
- 如abcdefabcdef
- X=abX=ab,X′=baX′=ba
- Y=cdefY=cdef,Y′=fedcY′=fedc
- (X′Y′)′=(bafedc)′=cdefab(X′Y′)′=(bafedc)′=cdefab
- 时间复杂度为O(N)O(N),空间复杂度为O(1)O(1)
- (X’Y’)’ = YX
代码实现
代码实现如CirculRotateString.hpp所示:
#ifndef CirculRotateString_hpp #define CirculRotateString_hpp #include <stdio.h> // 翻转字符串s的from到to1的字符 void reverseString(cahr* s, int from, int to) { while (from < to) { char t = s[from]; s[from++] = s[to]; s[to--] = t; } } // 长度为n的字符串循环左移m位 void leftRotateString(char* s, int n, int m) { m %= n; // 循环左移m位和循环左移(m%=n)位等价 reverseString(s, 0, m-1); // 翻转0~(m-1)区间的字符串 reverseString(s, m, n-1); // 翻转m~(n-1)之间的字符串 reverseString(s, 0, n-1); // 翻转0~(n-1)之间的字符串 } #endif /* CirculRotateString_hpp */