《剑指offer》42:翻转单词顺序
2016-08-21 19:53
302 查看
这个单元有两道题,都是字符串操作,挺简单的,不过如果没经历过思考的过程,可能就不是那么容易了,简单 != 容易。
书里安排了比较简单的左旋字符串在后面,我觉得反了,所以换了顺序来说。
每次移动的时间复杂度都是O(n),总的复杂度就是O(kn),k最多可以为n-1,所以复杂度最坏可达到O(n^2)!
假设k=3,则需要把”123456789”->”456789123”。看仔细一下,其实是把字符串分成两部分,”123”和”456789”,想把它们两个交换位置而已!
两部分的长度不一样,否则就可以简单地交换了。
不妨先反转整个字符串一遍:987654321。
可以发现,两部分已经到了它们所需要到的位置了,123到了末端,456789到了开头,只不过它们现在都是反转过来了而已,只需要各自再反转一遍就可以了!!!
最后,要注意处理一下,
要求:用O(1)的空间和O(n)的时间。
其实原理跟上面的是一样的,只是单词的数量多了,需要用空格将彼此区分开而已~
书里安排了比较简单的左旋字符串在后面,我觉得反了,所以换了顺序来说。
左旋字符串
将一个字符串“左移”k位,比如”123456789”左移3位变成”456789123”。最笨的方法
逐个向左移动,比如123456789->234567891->345678912->…每次移动的时间复杂度都是O(n),总的复杂度就是O(kn),k最多可以为n-1,所以复杂度最坏可达到O(n^2)!
假设k=3,则需要把”123456789”->”456789123”。看仔细一下,其实是把字符串分成两部分,”123”和”456789”,想把它们两个交换位置而已!
两部分的长度不一样,否则就可以简单地交换了。
不妨先反转整个字符串一遍:987654321。
可以发现,两部分已经到了它们所需要到的位置了,123到了末端,456789到了开头,只不过它们现在都是反转过来了而已,只需要各自再反转一遍就可以了!!!
最后,要注意处理一下,
k = k % str.size(),然后看k等于0的话,就不用处理了,原因就不多说了~应该挺明显的
#include <iostream> #include <string> using namespace std; void reverseHelper(string& str, int beg, int end) { for (int i = beg, j = end; i < j; ++i, --j) swap(str[i], str[j]); } void reverseWord(string& str, int k) { int len = str.size(); k = k % len; if (k > 0) { reverseHelper(str, 0, k-1); reverseHelper(str, k, len-1); reverseHelper(str, 0, len-1); } } int main() { string str = "hi jacket"; reverseWord(str, 2); cout << "Finally, str=" << str << endl; return 0; }
翻转单词顺序
把一个句子的单词为A B C …,变为… C B A,比如”hello world”变为”world hello”,而”I am a student.”变为”student. a am I”,也就是说,标点符号跟随它前一个单词在一起。要求:用O(1)的空间和O(n)的时间。
其实原理跟上面的是一样的,只是单词的数量多了,需要用空格将彼此区分开而已~
#include <iostream> #include <string> using namespace std; void reverseHelper(string& str, int beg, int end) { for (int i = beg, j = end; i < j; ++i, --j) swap(str[i], str[j]); } void reverseSentence(string& str) { int len = str.size(), i = -1, last = 0; reverseHelper(str, 0, len-1); while (++i <= len) { // 这是我目前能想到的最优美的写法了!!! if (i == len || str[i] == ' ') { reverseHelper(str, last, i-1); last = i + 1; } } } int main() { string str = "I am a student."; reverseSentence(str); cout << "Finally, str=" << str << endl; return 0; }
相关文章推荐
- 《剑指Offer》学习笔记--面试题42:翻转单词顺序VS坐旋转字符串
- 剑指offer解题报告(Java版)——翻转单词顺序 左旋字符串 42
- 《剑指offer》:[42]翻转英文中单词顺序
- 剑指offer——面试题42:翻转单词顺序VS左旋转字符串
- 剑指offer 面试题42 翻转单词顺序
- (剑指Offer)面试题42:翻转单词顺序
- 剑指offer-面试题42-翻转单词顺序VS左旋转字符串
- 剑指Offer 42题 翻转单词顺序 Java版
- 剑指Offer系列-面试题42:翻转单词顺序和左旋转字符串
- [剑指offer][面试题42]翻转单词顺序 VS 左旋转字符串
- 【剑指offer-Java版】42翻转单词顺序VS左旋转字符串
- 剑指offer--面试题42: 翻转单词顺序列 vs 左旋转字符串
- 剑指offer-面试题42:翻转单词顺序VS左旋转字符串
- 剑指offer 面试题42 翻转单词顺序 VS 左旋转字符串
- 剑指offer——面试题42:(一)翻转单词顺序
- 《剑指Offer》面试题:翻转单词顺序
- 面试题42:翻转单词顺序 VS 左旋转字符串
- 面试 42-1:翻转单词顺序
- 【剑指Offer学习】【面试题42:翻转单词顺序vs左旋转字符串】
- 面试题42:翻转单词顺序 || 左旋字符串