字符串相关算法1-字符串旋转

给你一串字符串,如何实现将将首部k个字符移动到字符串后边而不改变其余字符的顺序?ios

最容易想到的是,咱们能够将须要移动的字符一个一个地移动到字符串的尾部。对于每次移动咱们只须要一个变量记录第一个字符,后边字符往前移动就行了算法

这里不给出这种实现的代码。spa

复杂度分析:长度为n的字符串,假如须要移动m个字符到字符串末尾,那么总共须要m x n 次操做,时间复杂度为O(mn)code

咱们仅须要一个变量存储第一个字符位置,空间复杂度为O(1)blog

 

有没有更高效的算法呢?ci

基于这样的事实:一个字符串翻转两次后与原来的字符串是相同的。字符串

所以咱们能够对字符串进行这样一个操做,对须要移动的字符子串和不须要移动的字符子串分开处理:string

首先对两个子串翻转一次,此时每一个子串间的相对位置是不变得io

而后对整个字符串再进行翻转,对于每一个字符子串而言因为翻转了两次,与原来字符字串是一致的;总体进行翻转,字符子串相对位置改变一次,至此咱们获得了符合要求的结果。class

代码以下:

 1 #include <iostream>
 2 #include <cstring>
 3 using namespace std;
 4 void RevString(char * s, int from, int to){
 5     while(from < to){
 6         swap(s[from++], s[to--]);
 7     }
 8 }
 9 void LeftRotateString(char *s, int n, int k){
10     RevString(s, 0, k - 1);
11     RevString(s, k, n - 1);
12     RevString(s, 0, n - 1);
13 }
14 int main(){
15     char s[1000];
16     int k;
17     while(cin >> s >> k){
18         LeftRotateString(s, strlen(s), k);
19         cout << s << endl;
20     }
21     return 0;
22 }

 

复杂度分析:长度为n的字符串,每一个字符串翻转了两次,时间复杂度为O(n)

相关文章
相关标签/搜索