《剑指Offer》-58-翻转单词顺序/力扣-151-反转字符串中的单词
可以使用栈,将每个单词(字符串)压栈,然后弹栈就 OK 了
好吧,实际写下来考虑到可能存在的多余空格问题,代码看起来并不简介,而且写之前就很明显直到需要最差额外 n 的空间,时间复杂度最差 2n,所以都不算好
思路是压栈的时候只压单词本身,弹栈的时候再去拼空格
string reverseWords(string s) { s += ' ';// 加一个空格避免需要额外清空temp stack<string> stk; string temp; for (char ch : s) { if (ch != ' ') temp += ch; else if (!temp.empty()) { stk.push(temp); temp.clear(); } } int numOfWord = stk.size(); if (numOfWord == 0) return ""; for (int i = 0; i < numOfWord - 1; i++) { temp = temp + stk.top() + ' '; stk.pop(); } return temp+stk.top(); }
需要额外注意栈空的情况,不然会指针越界
然后就是这种做法真的 时间/空间复杂度 都很差
string reverseWords(string s) { string temp,res; int notZero = 0; while (s[notZero] == ' ') notZero++; // 从后往前扫描,最后一位不能是0 for (int i = s.size() - 1; i >= notZero; i--) { if (s[i] != ' ') temp.insert(temp.begin(),s[i]); else if (!temp.empty()) { res = res + temp + " "; temp.clear(); } } return res+temp; }
换一个思路,效率仍然很差,我觉得问题出在insert()
之后每次的移动上面
最终思路我想应该是将每一个单词翻转,然后将整个字符串翻转
string reverseWords(string s) { s += ' '; int start = 0, end; while (s[start] == ' ') s.erase(s.begin()); for (; start < s.size(); start++) { if (s[start] != ' ') { for (end = start + 1; end < s.size(); end++) { if (s[end] == ' ') { reverse(s.begin() + start, s.begin() + end); start = end; break; } } } } reverse(s.begin(), s.end());// 至此完成翻转,接下来提取单词 start = 0; while (s[start] == ' ') s.erase(s.begin()); // 删除中间多余空格 for (start = 0; start < s.size(); start++) { if (s[start] == ' ' && (start + 1) < s.size()) { while (s[start + 1] == ' ')s.erase(s.begin() + start + 1); } } return s; }
AC 代码,不能说是最完美的,但是应该足够完美了,有几个巧思
- s 一上来就追加一个
' '
,这样可以保证挨个单词翻转的时候不用追加最后一步操作 - 翻转前删除头部所有空格,翻转后再删除一遍头部所有空格(其实就是没翻转前的尾空格),这样也删除了第一步自己追加的空格,这样做很省事也很见简单
另外就是原地操作数组需要格外注意指针越界的情况
string reverseWords(string s) { int len = s.size(); int start = 0, end = 0; bool wordStarted = false; for (int i = 0; i < len; i++) { if (s[i] != ' ') { if (!wordStarted) { if (start != 0) s[end++] = ' '; // 添加空格分隔符 start = end; // 记录单词起始位置 wordStarted = true; } s[end++] = s[i]; // 复制字符 } else { wordStarted = false; } } s.resize(end); // 调整字符串长度 reverse(s.begin(), s.end()); // 整体翻转字符串 start = 0; len = s.size(); for (int i = 0; i < len; i++) { if (s[i] != ' ' || (i > 0 && s[i - 1] != ' ')) { s[start++] = s[i]; // 去除多余空格 } } s.resize(start); return s; }
GPT 给出的时间复杂度可以优化至O(N)
的代码(未验证)
本文作者:YaosGHC
本文链接:https://www.cnblogs.com/yaocy/p/17625862.html
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步