Leetcode344. 反转字符串
题目链接:
思路:
- 简单思路头尾交换
class Solution {
public:
void reverseString(vector<char>& s) {
int i=0;
int j=s.size()-1;
while(i<j)
{
swap(s[i],s[j]);
i++;
j--;
}
}
};
Leetcode541. 反转字符串 II
题目链接:
[541. 反转字符串 II - 力扣(Leetcode)]:
思路:
-
在遍历字符串的过程中,只要让 i += (2 * k),i 每次移动 2 * k 就可以了,然后判断是否需要有反转的区间。
因为要找的也就是每2 * k 区间的起点。
class Solution {
public:
string reverseStr(string s, int k) {
for(int i=0;i<s.size();i+=(2*k))
{
if(i+k<=s.size()){
reverse(s.begin()+i,s.begin()+i+k);
}else{
reverse(s.begin()+i,s.end());
}
}
return s;
}
};
Leetcode剑指 Offer 05. 替换空格
题目链接:
[剑指 Offer 05. 替换空格 - 力扣(Leetcode)]:
思路:
- 避免用额外辅助空间:从后向前双指针
-
很多数组填充类的问题,都可以先预先给数组扩容带填充后的大小,然后在从后向前进行操作。
这么做有两个好处:
- 不用申请新数组。
- 从后向前填充元素,避免了从前向后填充元素时,每次添加元素都要将添加元素之后的所有元素向后移动的问题。
class Solution {
public:
string replaceSpace(string s) {
int count=0;
int size1=s.size();
for(int i=0;i<s.size();i++)
{
if(s[i]==' ')
{
count++;
}
}
s.resize(size1+2*count);
int size2=s.size();
for(int i=size1,j=size2;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;
}
};
Leetcode151. 反转字符串中的单词
题目链接:
[151. 反转字符串中的单词 - 力扣(Leetcode)]:
思路:
- 去除空格
- 字符串翻转
- 单词翻转
class Solution {
public:
string reverseWords(string s) {
removeExtraSpaces(s);
reverse(s,0,s.size()-1);
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;
}
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;
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的大小即为去除多余空格后的大小。
}
};
Leetcode剑指 Offer 58 - II. 左旋转字符串
题目链接:
[剑指 Offer 58 - II. 左旋转字符串 - 力扣(Leetcode)]:
思路:
- 备考做过类似的 记住即可
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;
}
};
总结
字符串问题做到尽量不调库,其中151理解稍微费时一些,去除空格的思路类比移除元素也花了好久才理解,其他感受就是:双指针好妙!!
C/C++语言中erase()函数的用法
-
(1)
erase(pos,n);
删除从pos
开始的n个字符,比如erase(0,1)
就是删除第一个字符 -
(2)
erase(position);
删除position
处的一个字符(position是个string类型的迭代器) -
(3)
erase(first,last);
删除从first到last之间的字符(first和last都是迭代器)