来到了字符串系列,
344.反转字符串leetcode 344
class Solution {
public:
void reverseString(vector<char>& s) {
for(int i=0,j=s.size()-1;i<s.size()/2;i++,j--)
{
swap(s[i],s[j]);
}
}
};
反转字符串,i和j分别是字符串的头和尾,两边同时遍历从而进行反转。
541.反转字符串II leetcode 541
利用reverse库函数,这里利用库函数来实现字符串反转。
先是遍历2k
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{
// 3. 剩余字符少于 k 个,则将剩余字符全部反转。
reverse(s.begin()+i,s.end());
}
}
return s;
}
};
在这里一个关键点是看是否剩余字符,所以加一个判断判断是否小于2k来看反转。
指offer05.替换空格 替换空格
class Solution {
public:
string replaceSpace(string s) {
//第一部分统计空格的数目
int count=0;
int oldsize=s.size();
for(int i=0;i<s.size();i++)
{
if(s[i]==' ')
{
count++;
}
}
//第二部分扩充变换以后的size
s.resize(s.size()+count*2);//这里让s.size()->s.resize()
int newsize=s.size();
//第三部分从后向前置换
for(int i=oldsize-1,j=newsize-1;i<j;i--,j--){
if(s[i]!=' ')
{
s[j]=s[i];
}
else{
s[j]='0';
s[j-1]='2';
s[j-2]='%';
j-=2;
}
}
return s;
}
很多数组填充类的问题,都可以先预先给数组扩容带填充后的大小,然后在从后向前进行操作。
这么做有两个好处:
1.不用申请新数组。.//节省了空间
2.从后向前填充元素,避免了从前向后填充元素时,每次添加元素都要将添加元素之后的所有元素向后移动的问题。
151.反转字符串里的单词
leetcode 151 Reverse Words in a String
反转字符串里的单词
I am a robot. 反转了后 robot a am I
想想咋做。。
第一个全都反转,swap(i,j),然后就变成tobor a ma I
然后再一个个反
然后蒙蔽直接傻眼,看不太懂了就,回去看视频慢慢扣
剑指Offer58-II.左旋转字符串 zuoxuan
输入: s = “abcdefg”, k = 2
输出: “cdefgab”
也是用的反转的思路,先翻转a和b,——>bacdefg
然后翻转cdefg——>bagfedc
然后直接全翻转——>cdefgab
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;
}
};
但这里我有一点不明白,s.begin()+n 第一段的翻转和第二段的翻转的界限问题。为啥都是begin+n