6.1 反转字符串
采用双指针进行翻转。可以通过字符串下标进行索引,也可以直接使用指针进行索引。
class Solution {
public:
void reverseString(vector<char>& s) {
// char*left = &s[0];
// char*right = &s[s.size()-1];
// while(right>left){
// char tmp = 0;
// tmp = *left;
// *left = *right;
// *right = tmp;
// left++;
// right--;
// }
for(int i=0,j=s.size()-1;i<j;i++,j--){
swap(s[i],s[j]);
}
}
};
6.2 反转字符串②
for循环步长确定为 i += (2*k);每次增加2k长度,
题目要求:
如果剩余字符少于 k 个,则将剩余字符全部反转。
如果剩余字符小于 2k 但大于或等于 k 个,则反转前 k 个字符,其余字符保持原样。
按照2k步长增加,剩余字符一定是小于,<=2k,因此循环中只需要判断剩余字符大于等于k还是小于k。
if(i+k < s.size()) 与 if(i+k <= s.size())都能通过
class Solution {
public:
string reverseStr(string s, int k) {
for(int i =0;i<s.size();i+=(2*k)){
//1.每隔2k个字符的前k个字符反转
//2.剩余字符小于2k,但大于等于k,则反转前k个
if(i+k < s.size()){
reverse(s.begin()+i,s.begin()+i+k);
}
else{
reverse(s.begin()+i,s.end());
}
}
return s;
}
};
可以自己实现一下 reverse 方法
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]);
}
}
string reverseStr(string s, int k) {
for(int i=0;i<s.size();i+=(2*k)){
//1.每隔2k个字符的前k个字符反转
//2.剩余字符小于2k,但大于等于k,则反转前k个
if(i+k <= s.size()){
reverse(s,i,i+k-1);
continue;
}
reverse(s,i,s.size()-1);
}
return s;
}
};
while循环实现
这个反转字符串,就两个规则,一个是pos一次增加2*k个,将字符串切成一段一段区间。另一个就是判断这个区间内剩余元素是否够k个,够的话就前k个交换,不够的话,区间内所有元素交换。
class Solution {
public:
string reverseStr(string s, int k) {
int pos = 0, n = s.size();
while(pos<n){
if(pos+k < n){
reverse(s.begin()+pos,s.begin()+pos+k);
}
else(reverse(s.begin()+pos,s.end()));
pos+=2*k;
}
return s;
}
};
6.3 替换数字
很多数组填充类的问题,其做法都是先预先给数组扩容带填充后的大小,然后在从后向前进行操作。
cin用来输入,记录老字符串的长度,然后通过for循环对数字进行计数。
扩充字符串长度,number长度为6,数字本身有一个位置,所以cnt*5即可。
双指针开始后移扩充。
#include <iostream>
using namespace std;
int main(){
string s;
while(cin >> s){
int cnt = 0;
int soldsize = s.size();
for(int i = 0;i < s.size();i++){
if(s[i]>='0'&&s[i]<='9'){
cnt++;
}
}
s.resize(soldsize+cnt*5);//空格的地方替换成number
int snewsize = s.size();
for(int i = soldsize-1,j = snewsize-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;
}
}
6.4.1 翻转字符串里的单词_版本1
首先将所有内容全部翻转,双指针快速交换。
然后去除多余的空格,双指针,fast先遍历字符串前面的空格,直到fast拿到第一个字符
然后开始往slow中传值,slow自加,fast遇到字符串中间的空格时,跳出本次循环开始下次循环。
字符串末尾空格处理。
class Solution {
public:
void removeExtraSpace(string& s){
}
void reverse(string& s,int start,int end){
for(int i=start,j=end;i<j;i++,j--){
swap(s[i],s[j]);
}
}
string reverseWords(string s){
reverse(s,0,s.size()-1);
removeExtraSpace(s);
int start = 0;
for(int i=0;i<=s.size();i++){
if(i == s.size() || s[i] ==' '){
reverse(s,start,i-1);
start = i+1;
}
}
return s;
}
};
6.4.2 翻转字符串里的单词_版本2
与版本1的不同为:removeSpace写的更加精简,也是双指针,slow必须要赋初值为0。
class Solution {
public:
void removeExtraSpace(string& s){
int slow = 0;
for(int i=0;i<s.size();i++){
if(s[i] != ' '){
if(slow != 0) s[slow++] = ' ';
while(i<s.size() && s[i] != ' '){
s[slow++] = s[i++];
}
}
}
s.resize(slow);
}
void reverse(string& s,int start,int end){
for(int i=start,j=end;i<j;i++,j--){
swap(s[i],s[j]);
}
}
string reverseWords(string s){
reverse(s,0,s.size()-1);
removeExtraSpace(s);
int start = 0;
for(int i=0;i<=s.size();i++){
if(i == s.size() || s[i] ==' '){
reverse(s,start,i-1);
start = i+1;
}
}
return s;
}
};
6.5 右旋字符串
题目要求为:给定字符串s和数字n,将倒数第n个字符到最后一个字符组成的字符串拼接到最前面。
方法:整体翻转+局部翻转
类似的题目:左旋字符串
#include <iostream>
#include<algorithm>
using namespace std;
void reverse(string& s,int start,int end){
for(int i=start,j=end;i<j;i++,j--){
swap(s[i],s[j]);
}
}
int main(){
int n;
string s;
cin >> n;
cin >> s;
reverse(s,0,s.size()-1);
reverse(s,0,n-1);
reverse(s,n,s.size()-1);
cout<<s<<endl;
}
6.6 实现strStr()
当出现字符串不匹配时,可以记录一部分之前已经匹配的文本内容,利用这些信息避免从头再去做匹配。
这部分确实有点儿难度,先过吧,后面有机会再琢磨。
class Solution {
public:
void getNext(int* next,const string& s){
int j = -1;
next[0] = j;
for(int i=1;i<s.size();i++){
while(j>=0 &&s[i] != s[j+1] ){
j = next[j];//向前回退
}
if(s[i] == s[j+1]){
j++;
}
next[i] = j;
}
}
int strStr(string haystack, string needle) {
if(needle.size() == 0){
return 0;
}
int next[needle.size()];
getNext(next,needle);
int j = -1;
for(int i=0;i<haystack.size();i++){
while(j>=0 && haystack[i] != needle[j+1]){
j = next[j];
}
if(haystack[i] == needle[j+1]){
j++;
}
if(j == needle.size()-1){
return (i-needle.size() + 1);
}
}
return -1;
}
};