算法研究(一) 旋转字符串的三种算法
来源:互联网 发布:宾馆307网络歌手 编辑:程序博客网 时间:2024/05/23 01:18
题目:给定一个长度为n的字符串,将它向左旋转i个位置,例如,str = "abcdefg", n = 7, i = 3,则旋转后,str = "defgabc",要求空间复杂度为1。
• 算法三:
一般,解旋转字符串这样的题目,最简单的做法即是先将前i个字符拷贝到临时空间,然后将后n - i个字符前移,最后再将临时空间中的数据拷贝到原字符串的后i个位置上。但这样做会额外浪费i个空间。现给出如下三种算法:
• 算法一:
void swap(char* str, int n, int i){ int j; for (j = 0; j < i; ++j) { int t = str[j]; str[j] = str[n - i + j]; str[n - i + j] = t; }}void rotate(char* str, int n, int i) { if (0 == i || n == i) return; int k = n - i; if (i < k) { swap(str, n, i); rotate(str, n - i, i); } else { swap(str, n, k); rotate(str + k, n - k, i - k); }}
• 算法二:
void reverse(char*str, int n) { int m = n / 2; int i; for (i = 0; i < m; ++i) { int t = str[i]; str[i] = str[ n - 1 - i]; str[n - 1 - i] = t; }}void rotate(char* str, int n, int i) { reverse(str, i); reverse(str + i, n - i); reverse(str, n);}
• 算法三:
int gcd(int m, int n) { int k = m % n; if (0 == k) return n; else return gcd(n, k);}void rotate(char* str, int n, int i) { int k = gcd(n, i); int init; for (init = 0; init < k; ++init) { int cur = init; char t = str[cur]; int next; for (next = (cur + i) % n; next != init; next = (cur + i) % n) { str[cur] = str[next]; cur = next; } str[cur] = t; }}
不难看出,这三种算法的空间复杂度都是1,而时间复杂度都是n。但,算法三实际上更加巧妙,它所用时间只是前两者的一半。
(注:最近看了STL关于rotate函数的源码,发现它这三种算法都用到了,其对应的迭代器 concept 分别是 ForwardIterator, BidrectionalIterator, RandomaccessIterator,不过我觉得由于前两种算法的效率是一样的,所以实际上不需要 BidrectionalIterator 版的算法。)
参考文献
《编程珠玑》(美)本特利(Bentley,J.)
- 算法研究(一) 旋转字符串的三种算法
- 算法研究(一) 旋转字符串的三种算法
- 旋转字符串的三种算法
- 旋转字符串的三种算法
- 算法之左旋转字符串(一)
- 字符串匹配算法研究(一)
- 有趣的算法-旋转字符串
- 俄罗斯方块旋转算法研究
- 每天学习一算法系列(24)(实现字符串左旋转的函数)
- 算法整理-字符串(LCS,旋转字符串)
- 搜索引擎算法研究(三)
- 算法研究(三) 巧用快排
- 算法研究(三) 巧用快排
- 旋转字符串算法由浅入深
- 算法 旋转字符串
- 字符串旋转检测算法
- 【算法】旋转字符串
- 【算法】旋转字符串
- hello world
- 1.面向对象的封装,构造函数!
- Apache Web Server性能测试中大量TIME_WAIT解决方法 及 Linux sysctl.conf 优化解决方案
- 一个合格的程序员应该读过哪些书
- android使用activitygroup和Scrollview的方法
- 算法研究(一) 旋转字符串的三种算法
- 很不错的Html,Javascript,CSS在线编译器
- 匿名对象
- 我是如何学PHP的
- Struts2框架中s:if标签和s:set标签小结
- Windows驱动中的电源管理
- Android 关闭线程(转)
- CentOS 卸载OpenJdk
- xargs 用法