多益网络2014校招的一道笔试题---左旋字符串
定义字符串的左旋转操作:把字符串前面的若干个字符移动到字符串的尾部。
如把字符串abcdef左旋转2位得到字符串cdefab。
请实现字符串左旋转的函数,分析算法复杂度
当时答的时候用的方法太渣了,
思路是每次左移一位,移动K次。
12345678→23456781→34567812→45678123
这是我写的实现代码
1 void LeftMove(char* str,int k,int n) 2 { 3 k = k%n; 4 if (NULL == str||k<1||n<1) 5 { 6 return; //输出合法性检测 7 } 8 while(k--) 9 { 10 int t = str[0]; 11 for(int i=1;i<n;i++) 12 { 13 str[i-1] = str[i]; 14 } 15 str[n-1] = t; 16 } 17 }
虽然这个算法可以实现数组的循环右移,但是算法复杂度为O(n^2)
后面在别人博客上看见一种比较简单有效而且复杂度比较好的方法---逆序
假设我要移动“12345678”的3位,我可以将字符串分为123,45678两部分
逆序排列123:321
逆序排列45678:87654
全部逆序32187654:45678123
这样也实现了左旋3位数
这是我实现的代码,已测试正确
1 char *Reverse(char *first,char *end) //逆序first指针到end指针之间的字符 2 { 3 char *temp =first; 4 if (first>=end||NULL==first||NULL==end) 5 { 6 return temp; 7 } 8 while (first<end) 9 { 10 swap(*first++,*end--); 11 } 12 return temp; 13 } 14 void swap(char&a,char&b) 15 { 16 char temp = a; 17 a = b; 18 b = temp; 19 } 20 char* LeftMove(char *str,int len,int n) //左旋函数 21 { 22 if (NULL==str||n<0) 23 { 24 return str; 25 } 26 n = n%len; 27 Reverse(str,str+n-1); 28 Reverse(str+n,str+len-1); 29 Reverse(str,str+len-1); 30 return str; 31 }
算法复杂度为O(n)
总之还得再继续努力,特别是在数据结构和算法要下工夫,这样下一次笔试就能胸有成竹了!