腾讯面试题--字符串旋转
2014-05-27 13:55
288 查看
首先,说明一下。我看过题解,至于文章算不算原创,我就不敢保证了。如果,不算原创,咱在这就对不起了。
题意呈上,望主子能理解:给你一串文本串str 与位移数k,现在让你在O(n)的时间复杂度,与O(1)的空间复杂度,是的原来的文本串整体位移K位。
例如:str = "abcdefg", k = 3;那么结果就应该是defgabc
目前为止:已经想到有3种方案,欢迎补充。
方案一:看题解的做法是:
1.假设串长为n;
2.先将原串分为两个字串;
3.如果左移那么就是str[0 … k-1]与str[k…n-1],反之为str[0 … len-k-1]与str[len - k - 1…n-1];
4.将两个字串各自翻转得到整体的str
5.再将最后的str翻转即可。
这样时间刚刚好为O(N);
演示一遍:str = "abcdefg", k = 3
1.n = strlen(str);
2.str[0…2] = “abc” str[3…6] = “defg”
3.翻转字串,得到str=“cbagfed”
4.最后在讲str翻转得:str = “defgabc”
方案二:自己的想法,不知道正确与否;
1.从原串中任意一处出发;
2.然后使用记录当前的位置上的字符,赋给想移位k的地方;
3.一直循环下去,知道循环位置达到n次后就停止;
例如:str=“abcd” k = 3 。我的初始地点第一位,那么可以得到:
第一趟:aacd ch=‘b’
第二趟:aabd ch=‘c’
第三趟:aabc ch=‘d’
第四趟:dabc 结束。
当str=“abcde” k=2是,我的思路如上图。
可后来我们考虑一下,如果如果n % k == 0,结果就不对,只是因为n = k * x,x为一个循环节。所以遇到此情况我们要特判。向前向后移一位继续进行下去,不过我不是很清楚这种方案是否可行。望大神指导,在下不甚欢喜。
方案三:这个方案来自于我的师弟;
1.将str[0…k - 1]与str[k…2*k- 1]交换,以此类推;
2.当出现len-xk<k时就改变k的循环节,使k=xk+k-len-1;
3.重复1,2步骤;直至到达最后的len。
例如:abcdefg 4
第一趟:efgdabc k=1
第二趟:efgadbc k = 1
第三趟:efgabdc k = 1
第四趟:efgabcd 结束
最后,电脑没装作图的,只能随便画了下,见谅。
第一次,写博客,见谅。
附代码两份,代码比较戳,见谅。
题意呈上,望主子能理解:给你一串文本串str 与位移数k,现在让你在O(n)的时间复杂度,与O(1)的空间复杂度,是的原来的文本串整体位移K位。
例如:str = "abcdefg", k = 3;那么结果就应该是defgabc
目前为止:已经想到有3种方案,欢迎补充。
方案一:看题解的做法是:
1.假设串长为n;
2.先将原串分为两个字串;
3.如果左移那么就是str[0 … k-1]与str[k…n-1],反之为str[0 … len-k-1]与str[len - k - 1…n-1];
4.将两个字串各自翻转得到整体的str
5.再将最后的str翻转即可。
这样时间刚刚好为O(N);
演示一遍:str = "abcdefg", k = 3
1.n = strlen(str);
2.str[0…2] = “abc” str[3…6] = “defg”
3.翻转字串,得到str=“cbagfed”
4.最后在讲str翻转得:str = “defgabc”
方案二:自己的想法,不知道正确与否;
1.从原串中任意一处出发;
2.然后使用记录当前的位置上的字符,赋给想移位k的地方;
3.一直循环下去,知道循环位置达到n次后就停止;
例如:str=“abcd” k = 3 。我的初始地点第一位,那么可以得到:
第一趟:aacd ch=‘b’
第二趟:aabd ch=‘c’
第三趟:aabc ch=‘d’
第四趟:dabc 结束。
当str=“abcde” k=2是,我的思路如上图。
可后来我们考虑一下,如果如果n % k == 0,结果就不对,只是因为n = k * x,x为一个循环节。所以遇到此情况我们要特判。向前向后移一位继续进行下去,不过我不是很清楚这种方案是否可行。望大神指导,在下不甚欢喜。
方案三:这个方案来自于我的师弟;
1.将str[0…k - 1]与str[k…2*k- 1]交换,以此类推;
2.当出现len-xk<k时就改变k的循环节,使k=xk+k-len-1;
3.重复1,2步骤;直至到达最后的len。
例如:abcdefg 4
第一趟:efgdabc k=1
第二趟:efgadbc k = 1
第三趟:efgabdc k = 1
第四趟:efgabcd 结束
最后,电脑没装作图的,只能随便画了下,见谅。
第一次,写博客,见谅。
附代码两份,代码比较戳,见谅。
#include <iostream>//自己的思路代码 using namespace std; #include <cstring> #include <string> const int MAX = 100 + 10; char str[MAX]; //int res(char *str, int ) int main() { int k, num, start, i;//start表示循环次数,num表示是否回到了循环起点,i跳转点。 char ch, s; while (cin >> str >> k) { int len = strlen(str); ch = str[len - 1]; start = 0, i = len - 1; num = len - 1; while (start++ < len) { s = str[(i + len - k) % len]; str[(i + len - k) % len] = ch; ch = s; i = (i + len - k) % len; if (i == ((num + k + len) % len) && start != len)//当发现找到循环节点,我们就将i移向下一位即可。 { str[num] = ch; start++; ch = str[(i + len + 1) % len]; num = i = (i + len + 1) % len; } } puts(str); } return 0; }
#include <iostream>//题解所述的代码 using namespace std; #include <cstring> #include <string> const int MAX = 100 + 10; char str[MAX]; int sum; void resarse(char *str, int start, int end) { while (start < end) { swap(str[start], str[end]); start++; end--; sum++; } } int main() { int k; while (cin >> str >> k) { int len = strlen(str); k %= len; sum = 0; resarse(str, 0, k - 1); resarse(str, k, len - 1); resarse(str, 0, len - 1); puts(str); printf("%d\n", sum); } return 0; }
#include <iostream>//方案三 using namespace std; const int MAX = 100 + 10; char str[MAX]; bool change(char *str, int start, int end, int k) { for(int i = start; i < end; i++) { if (end - i - 1 >= k) { swap(str[i], str[i + k]); if (end - i - 1 == k && end % k == 0) return true;//找到最后一个循环节点 } else { if (end == i + 1) return true; k = k + i - end + 1;//将循环节点改变,类似于辗转相除 if (change(str, i, end, k)) return true; } } } int main() { int k, i; while (cin >> str >> k) { int len = strlen(str); change(str, 0, len, k); puts(str); } return 0; }
相关文章推荐
- 程序员面试题精选100题(21)-左旋转字符串
- 面试题---->旋转字符串
- 剑指offer 面试题42—翻转单词顺序VS左旋转字符串
- 面试题42:翻转单词顺序VS左旋转字符串
- 【剑指Offer学习】【面试题42:翻转单词顺序vs左旋转字符串】
- 程序员面试题精选100题(21)-左旋转字符串
- 【剑指offer】面试题42:左旋转字符串
- 面试题42:翻转单词顺序VS左旋转字符串
- 剑指offer 面试题42 翻转单词顺序 | 左旋转字符串
- 剑指Offer面试题42(Java版):反转单词顺序VS左旋转字符串
- 面试题---->旋转字符串
- [剑指offer][面试题42]翻转单词顺序 VS 左旋转字符串
- 面试题42:左旋转字符串
- 程序员面试题精选(21):左旋转字符串
- [每日练习]面试题--判断某个字符串是否为另一个字符串旋转得到的
- 程序员面试题100题第21题——左旋转字符串
- 腾讯面试题 替换字符串
- 【面试题042】翻转单词顺序VS左旋转字符串
- 九章算法面试题55 旋转字符串
- 剑指offer——面试题42:(二)字符串的坐旋转操作