344. 反转字符串
#include<bits/stdc++.h> using namespace std; class Solution { public: void reverseString(vector<char>& s) { int len = s.size(); for(int i=0, j=len-1;i<j;i++,j--){ //第一种 // int temp = s[i]; // s[i] = s[j]; // s[j] = temp; //第二种 // s[i] ^= s[j]; // s[j] ^= s[i]; // s[i] ^= s[j]; swap(s[i],s[j]); } return ; } };
541. 反转字符串II
- 注意for循环表达式设计,i += 2*k,每次移动2*k长度
class Solution { public: void reverse(string &s, int i, int j){ while(i<j){ int temp = s[i]; s[i] = s[j]; s[j] = temp; i++; j--; } return; } string reverseStr(string s, int k) { for(int i=0;i<s.size(); i += 2*k){ if(i+k<=s.size()){ reverse(s,i,i+k-1); } else{ reverse(s,i,s.size()-1); } } return s; } };
剑指offer 05. 替换空格
- 使用replace()函数
class Solution { public: string replaceSpace(string s) { string c = "%20"; for(int i=0;i<s.size();i++){ if(s[i]==' '){ s.replace(i,1,c); } } return s; } };
- 不用replace()函数,且原地替换
class Solution { public: string replaceSpace(string s) { int count = 0; // 统计空格的个数 int sOldSize = s.size(); for (int i = 0; i < s.size(); i++) { if (s[i] == ' ') { count++; } } // 扩充字符串s的大小,也就是每个空格替换成"%20"之后的大小 s.resize(s.size() + count * 2); int sNewSize = s.size(); // 从后先前将空格替换为"%20" for (int i = sNewSize - 1, j = sOldSize - 1; j < i; i--, j--) { if (s[j] != ' ') { s[i] = s[j]; } else { s[i] = '0'; s[i - 1] = '2'; s[i - 2] = '%'; i -= 2; } } return s; } };
151. 翻转字符串里的单词
- 一般思路
class Solution { public: string reverseWords(string s) { vector<string> a; string ans = ""; for(int i=0;i<s.size();i++){ if(s[i]!=' '){ ans += s[i]; } if(s[i] ==' '&&ans!=""){ a.push_back(ans); ans = ""; } } if(ans!=""){ a.push_back(ans); } ans = ""; for(int i=a.size()-1;i>=0;i--){ if(i==0){ ans += a[i]; } else{ ans += a[i] + ' '; } } return ans; } };
- 空间复杂度O(1)
-
- 移除多余空格
- 将整个字符串反转
- 将每个单词反转
class Solution { public: void reverse(string& s, int start, int end){ //翻转,区间写法:左闭右闭 [] for (int i = start, j = end; i < j; i++, j--) { swap(s[i], s[j]); } } void removeExtraSpaces(string& s) {//去除所有空格并在相邻单词之间添加空格, 快慢指针。 int slow = 0; //整体思想参考https://programmercarl.com/0027.移除元素.html for (int i = 0; i < s.size(); ++i) { // if (s[i] != ' ') { //遇到非空格就处理,即删除所有空格。 if (slow != 0) s[slow++] = ' '; //手动控制空格,给单词之间添加空格。slow != 0说明不是第一个单词,需要在单词前添加空格。 while (i < s.size() && s[i] != ' ') { //补上该单词,遇到空格说明单词结束。 s[slow++] = s[i++]; } } } s.resize(slow); //slow的大小即为去除多余空格后的大小。 } string reverseWords(string s) { removeExtraSpaces(s); //去除多余空格,保证单词之间之只有一个空格,且字符串首尾没空格。 reverse(s, 0, s.size() - 1); int start = 0; //removeExtraSpaces后保证第一个单词的开始下标一定是0。 for (int i = 0; i <= s.size(); ++i) { if (i == s.size() || s[i] == ' ') { //到达空格或者串尾,说明一个单词结束。进行翻转。 reverse(s, start, i - 1); //翻转,注意是左闭右闭 []的翻转。 start = i + 1; //更新下一个单词的开始下标start } } return s; } };
剑指Offer58-II. 左旋转字符串
- 只能在原串操作
- 局部反转+整体反转:假设串s = a + b;要得到 s = b + a,可以
- 1.反转子串a
- 2.反转子串b
- 3.反转s
- 局部反转+整体反转:假设串s = a + b;要得到 s = b + a,可以
class Solution { public: string reverseLeftWords(string s, int n) { reverse(s.begin(), s.begin() + n); reverse(s.begin() + n, s.end()); reverse(s.begin(), s.end()); return s; } };
28. 实现strStr()
- 子串问题,如判断字符串A是否出现在字符串B中,并求出现次数。KMP求解
- 关键点:构造前缀表(不减一版本,即最长相等前后缀)
C++ AC code:
#include<bits/stdc++.h> using namespace std; class Solution { public: //构造next数组(即最长相等前后缀) void getNext(int *next, string s){ int j = 0; next[0] = 0; for(int i=1;i<s.size();i++){ while(j>0&&s[i]!=s[j]){ j = next[j-1]; } if(s[i] == s[j]){ j++; } next[i] = j; } return; } int strStr(string haystack, string needle) { int len = needle.size(); int next[len]; getNext(next,needle); int j = 0; for(int i=0;i<haystack.size();i++){ while(j>0&&haystack[i]!=needle[j]){ j = next[j-1]; } if(haystack[i]==needle[j]){ j++; } if(j==len){ return i-len+1; } } return -1; } };
459. 重复的子字符串
- 令s = s′s′⋯s′s′,则有ss = s + s,掐头去尾后,如果能在ss中finds,则true,否则false,必要性证明略。
#include<bits/stdc++.h> using namespace std; class Solution { public: bool repeatedSubstringPattern(string s) { string ss = s + s; ss.erase(ss.begin());//删头 ss.erase(ss.end()-1);删尾 if(ss.find(s) != string::npos){ return true; } else{ return false; } } };
字符串总结
- 对于C,字符串数组以'\0'结束符结尾,需遍历求长,即while(str[i]!='\0')
- 对于C++,提供string类,有size接口,可直接str.size()求长
- 一些技巧:原地操作、双指针、反转、KMP(重点理解next数组,最长相等前后缀)
标签:string,int,随想录,笔记,空格,字符串,public,size From: https://www.cnblogs.com/daxiawan2022/p/17684270.html