(8/60)反转字符串、反转字符串Ⅱ、替换数字、翻转字符串里的单词、右旋转字符串
反转字符串
leetcode:344. 反转字符串
双指针法
思路
双指针中间靠拢,靠拢过程同时引入第三只被子以交换两个杯子的水。
复杂度分析
时间复杂度:O(N)。遍历一遍字符串
空间复杂度:O(1)。
注意点
- while条件是
left < right
。 - 可以用
swap()
函数交换两个数的值。
代码实现
class Solution { public: // 双指针法 void reverseString(vector<char>& s) { int left = 0; int right = s.size() - 1; while(left < right){ char temp = s[left]; s[left++] = s[right]; s[right--] = temp; } } }; // ---------------升级版----------------------- void reverseString(vector<char>& s) { for (int i = 0, j = s.size() - 1; i < s.size()/2; i++, j--) { swap(s[i],s[j]); } }
反转字符串Ⅱ
leetcode:541. 反转字符串 II
迭代法
思路
剩余字符数量>=k
为一组,对前k个字符进行reverse
操作;不足k为另一组,反转剩余所有字符。
复杂度分析
时间复杂度:O(N)。
空间复杂度:O(1)。
注意点
- 不要下意识就写i++,步长要使用合适的值。
- reverse(),传入参数为始、末迭代器,左闭右开。
代码实现
class Solution { public: string reverseStr(string s, int k) { // 步长为2*k for(int i = 0;i < s.size();i += 2*k){ // 剩余字符>=k个,反转前k个字符 if(s.size() - i>= k){ reverse(s.begin() + i,s.begin()+ i + k); }else{ reverse(s.begin()+i,s.end()); } } return s; } };
替换数字
卡码网:替换数字(第八期模拟笔试)
双指针法
思路
- 根据数字个数,计算变换后的字符串大小并更改。
- 双指针从后往前遍历,如果是非数字,则前指针赋值给后指针;否则后指针从后往前倒置入"number"
复杂度分析
时间复杂度:O(N)。
空间复杂度:O(1)。
注意点
- 字符串s.resize(),改变字符串大小。
代码实现
#include<iostream> using namespace std; int main(){ string s; while(cin >> s){ int count = 0; for(int i = 0;i < s.size();i++){ // 统计数字个数 if(s[i] >= '0' && s[i] <= '9'){ count++; } } int oldSize = s.size(); // 重新分配字符串大小 s.resize(s.size() + count*5); int newSize = s.size(); for(int i = oldSize - 1,j = newSize - 1; i < j; i--,j--){ // 如果是字符,则复制过去 if(s[i] > '9' || s[i] < '0'){ s[j] = s[i]; }else{ s[j] = 'r'; s[j - 1] = 'e'; s[j - 2] = 'b'; s[j - 3] = 'm'; s[j - 4] = 'u'; s[j - 5] = 'n'; j-=5; } } cout << s <<endl; } }
反转字符串中的单词
leetcode:151. 反转字符串中的单词
双指针法
思路
核心问题:去除多余空格
满足单词倒序只需:字符串整体反转,再反转串中的单词。
- 除第一个单词外
- fast指针移动到非空字符,
复杂度分析
时间复杂度:O(N)。去除空格遍历字符串一次;整个字符串反转遍历字符串一次;每个单词反转也遍历字符串一次。
空间复杂度:O(1)。
注意点
- 位运算也可以交换两数
- 访问数组下标前一定要确保下标在数组范围内。
代码实现
class Solution { public: // 左闭右闭 void reverseStr(string& s,int left,int right){ if(right < s.size()){ while(left < right){ swap(s[left++],s[right--]); } } } // 双指针法 string reverseWords(string s) { vector<string> str; // 首先去除多余空格 // 然后整体反转一次,再对单词反转一次 int slow = 0; int fast = 0; // ----------去除多余空格----------- while(fast < s.size()){ while(s[fast] == ' ') // fast找非' ' fast++; // fast不是字符串末端时单词前填' ' if(fast < s.size() && slow > 0) s[slow++] = ' '; // 填充非空字符 while(fast < s.size() && s[fast] != ' '){ s[slow++] = s[fast++]; } } s.resize(slow); // ----------去除多余空格----------- reverseStr(s,0,s.size()-1); // ----------反转单词--------------- slow = 0; fast = 0; while(fast < s.size()){ // while(fast < s.size() && s[fast] != ' '){ fast++; } // 反转单词 reverseStr(s,slow,fast - 1); slow = fast + 1; fast = slow; } // ----------反转单词--------------- return s; } };
右旋字符串
卡码网:右旋字符串(第八期模拟笔试)
反转字符串法
思路
可以看做是两段字符串调换位置,利用反转字符串里的单词的方法。
复杂度分析
时间复杂度:O(N)。reverse的时间复杂度为O(N)。
空间复杂度:O(1)。
注意点
- reverse()在algorithm头文件中。
代码实现
#include<iostream> #include<algorithm> using namespace std; int main(){ int k = 0; string s = ""; cin >> k; cin >> s; reverse(s.begin(),s.end()); reverse(s.begin(),s.begin() + k); reverse(s.begin() + k, s.end()); cout << s << endl; }
分类:
算法
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· 什么是nginx的强缓存和协商缓存
· 一文读懂知识蒸馏
· Manus爆火,是硬核还是营销?