代码随想录刷题随记7-字符串1
文章目录
- 代码随想录刷题随记7-字符串1
- 344.反转字符串
- 541. 反转字符串II
- 替换数字
- 151.翻转字符串里的单词
- 右旋字符串
344.反转字符串
leetcode链接
主要的难点在于使用 O(1) 的额外空间解决这一问题
反转字符串依然是使用双指针的方法
swap可以有两种实现。
一种就是常见的交换数值:
一种就是通过位运算,这个之前没见过,这里记录一下
s[i] ^= s[j];
s[j] ^= s[i];
s[i] ^= s[j];
解题代码
class Solution {
public:
void swap(vector<char>& s,int i,int j){
if(i==j){
return;
}
s[i]^=s[j];
s[j]^=s[i];
s[i]^=s[j];
}
void reverseString(vector<char>& s) {
int i=0;
int j=s.size()-1;
while(j>i){
swap(s,i,j);
i++;
j--;
}
}
};
541. 反转字符串II
leetcode链接
整体反转的思路和上一道题目一样
在遍历字符串的过程中,只要让 i += (2 * k),i 每次移动 2 * k 就可以了,然后判断是否需要有反转的区间。
解题代码:
class Solution {
public:
void swap(string &s,int i,int j){
if(i==j){
return;
}
char tmp=s[i];
s[i]=s[j];
s[j]=tmp;
}
void reverse(string & s,int i,int j){
while(i<j){
swap(s,i,j);
i++;
j--;
}
}
string reverseStr(string s, int k) {
for(int i=0;i<s.size();i+=(2*k)){
//剩余的字符大于等于k小于等于2k
if(i+k<=s.size()){
reverse(s,i,i+k-1);
continue;
}
//剩余小于k
reverse(s,i,s.size()-1);
}
return s;
}
};
替换数字
题目链接
可以用双指针法实现空间复杂度为O(1)的,但这种方法java里面不适用。
为啥要从后往前遍历:因为前面一截是没转化为number的字符串,如果从前往后遍历就会被覆盖。
解题源码:
#include<string>
#include<iostream>
using namespace std;
int main(){
string s;
char chars[6]={'r','e','b','m','u','n'};
while(cin>>s){
int count=0;
for(int i=0;i<s.size();i++){
if(s[i]>='0'&&s[i]<='9'){
count++;
}
}
int i=s.size()-1;
s.resize(s.size()+count*5);
int j=s.size()-1;
while(i>=0){
if(s[i]>='0'&&s[i]<='9'){
// for(int k=0;k<6;k++){
// s[j]=chars[k];
// j--;
// }
s[j-5] = 'n';
s[j-4] = 'u';
s[j-3] = 'm';
s[j-2] = 'b';
s[j-1] = 'e';
s[j] = 'r';
j -= 5;
}
else{
s[j]=s[i];
}
i--;
j--;
}
cout << s << endl;
}
}
151.翻转字符串里的单词
leetcode链接
用栈实现
解题代码:
class Solution {
public:
string reverseWords(string s) {
vector<string> stack;
int top=-1;
int pre=0;
int flag=0;
for(int i=0;i<s.size();i++)
{
if(s[i]==' '){
if(flag!=0){
stack.push_back(s.substr(pre,i-pre));
top++;
}
while(s[i]==' ') i++;
pre=i;
}
if(s[i]!=' ')
flag=1;
}
if(s[s.size()-1]!=' '){
stack.push_back(s.substr(pre,s.size()-pre));
top++;
}
string ret="";
for(;top>=0;top--){
ret+=stack[top];
if(top!=0)
ret+=" ";
}
return ret;
}
};
右旋字符串
题目链接
先把子串反转一遍,再整个反转一遍。负负得正就起到了整体的效果。
解题代码
#include<iostream>
using namespace std;
void reverse(string & s,int i,int j){
if(i== j)
return;
while(i<j){
char tmp=s[i];
s[i]=s[j];
s[j]=tmp;
i++;
j--;
}
}
int main(){
int k;
string s;
cin>>k;
cin>>s;
reverse(s,0,s.size()-k-1);
reverse(s,s.size()-k,s.size()-1);
reverse(s,0,s.size()-1);
cout<<s<<endl;;
}