剑指 Offer 05. 替换空格
题目
https://leetcode.cn/problems/ti-huan-kong-ge-lcof/
题解
class Solution {
public:
string replaceSpace(string s) {
int count = 0;
for(int i = 0;i < s.size();i++)
{
if(s[i] == ' ')
count++;
}
string t(s.size() + count * 2,'0');
int index = s.size() + count * 2 - 1;
for(int i = s.size() - 1;i >= 0;i--)
{
if(s[i] == ' ')
{
t[index] = '0';
t[index - 1] = '2';
t[index - 2] = '%';
index = index - 3;
}
else
{
t[index] = s[i];
index--;
}
}
return t;
}
};
注意
1.对字符串进行初始化
https://blog.csdn.net/VariatioZbw/article/details/116592225
151. 反转字符串中的单词
题目
https://leetcode.cn/problems/reverse-words-in-a-string/
题解
class Solution {
public:
string reverseWords(string s) {
if(s.size() == 1)
return s;
int slow = 0;
for(int fast = 0;fast < s.size();fast++)
{
if(s[fast] != ' ' )
{
if(slow != 0)
{
s[slow] = ' ';
slow++;
}
while(s[fast] != ' '&& fast < s.size())
{
s[slow] = s[fast];
slow++;
fast++;
}
}
}
s.resize(slow);
int left = 0;
int right = slow - 1;
while(left < right)
{
char temp = s[left];
s[left] = s[right];
s[right] = temp;
left++;
right--;
}
left = 0;
for(int i = 0;i <= s.size();i++)
{
if(s[i] == ' '||i == s.size() )
{
int right = i - 1;
while(left < right)
{
char temp = s[left];
s[left] = s[right];
s[right] = temp;
left++;
right--;
}
left = i + 1;
cout<<s<<endl;
}
}
return s;
}
};
注意
1.思路
①去除多余空格
②整个字符串进行反转
③字符串中的单词进行反转
2.针对删除空格的代码:
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的大小即为去除多余空格后的大小。
}
a)该逻辑中本身已经包括当(s[i] == ’ ')时快指针(i)就会自动+1的情况
b)若while的逻辑放入if (slow != 0)的代码块中,则会出现两个问题:①当slow0时,算法不会随字符串进行处理,则无法删除开头的字符串②若用else加入对slow0时进行处理,则删除开头的空格后,就会在第一个单词的第二个字符前加上空格
错误代码如下
int slow = 0;
for(int fast = 0;fast < s.size();fast++)
{
if(s[fast] != ' ' )
{
if(slow != 0)
{
s[slow] = ' ';
slow++;
while(s[fast] != ' '&& fast < s.size())
{
s[slow] = s[fast];
slow++;
fast++;
}
}
else
{
s[slow] = s[fast];
slow++;
}
}
}
c)直接对字符串进行重新设置大小(resize)可删除最后的空格
3.对字符串整体反转后,针对单词进行反转时,注意循环终止条件为
i <= s.size()
否则会跳过在对最后一个单词进行反转时会跳过最后一个字符,且判断是否反转时也需要加上判断条件
i == s.size()
否则会跳过最后一个单词
剑指 Offer 58 - II. 左旋转字符串
题目
https://leetcode.cn/problems/zuo-xuan-zhuan-zi-fu-chuan-lcof/
题解
class Solution {
public:
string reverseLeftWords(string s, int n) {
int left = 0;
int right = s.size() - 1;
while(left < right)
{
char temp = s[left];
s[left] = s[right];
s[right] = temp;
left++;
right--;
}
left = 0;
right = s.size() - 1 - n;
while(left < right)
{
char temp = s[left];
s[left] = s[right];
s[right] = temp;
left++;
right--;
}
left = s.size() - 1 - n + 1;
right = s.size() - 1 ;
while(left < right)
{
char temp = s[left];
s[left] = s[right];
s[right] = temp;
left++;
right--;
}
return s;
}
};
注意
思路:先整体,再局部。