字符串1
● 344.反转字符串
题目描述
编写一个函数,其作用是将输入的字符串反转过来。输入字符串以字符数组 s
的形式给出。
不要给另外的数组分配额外的空间,你必须**原地修改输入数组**、使用 O(1) 的额外空间解决这一问题。
示例 1:
输入:s = ["h","e","l","l","o"]
输出:["o","l","l","e","h"]
解题思路
双指针交换。
代码实现
class Solution {
public:
void reverseString(vector<char>& s) {
//双指针交换
int len=s.size();
int i=len/2;//需要交换的次数
char tmp=0;
int left=0,right=len-1;
while(i--)
{
tmp=s[left];
s[left++]=s[right];
s[right--]=tmp;
}
}
};
总结
● 541. 反转字符串II
题目描述
给定一个字符串 s
和一个整数 k
,从字符串开头算起,每计数至 2k
个字符,就反转这 2k
字符中的前 k
个字符。
-
如果剩余字符少于
k
个,则将剩余字符全部反转。 -
如果剩余字符小于
2k
但大于或等于k
个,则反转前k
个字符,其余字符保持原样。 -
示例 1:
输入:s = "abcdefg", k = 2 输出:"bacdfeg"
解题思路
双指针交换
代码实现
class Solution {
public:
string reverseStr(string s, int k) {
int len=s.size();
int count=len/2/k;//需要反转的轮数
if (len%(2*k))
{
count++;
}
int i=0,left=0,right=0,tmp=0;//第i轮
while(count--)
{
left=2*k*i;
right=((left+k-1)<(len-1))?(left+k-1):(len-1);
cout<<left<<" "<<right<<endl;
i++;
while(left<right)
{
tmp=s[left];
s[left++]=s[right];
s[right--]=tmp;
}
}
return s;
}
};
总结
● 剑指Offer 05.替换空格
题目描述
请实现一个函数,把字符串 s
中的每个空格替换成"%20"。
示例 1:
输入:s = "We are happy."
输出:"We%20are%20happy."
解题思路
代码实现
class Solution {
public:
string replaceSpace(string s) {
//统计空格数量
int count=0;
for(int i=0;i<s.size();i++)
{
if(s[i]==' ')
{
count++;
}
}
int len=s.size();
s.resize(len+count*2);
//在扩容的s中倒着往里放字符
int right=len+count*2-1;
int left=len-1;
for(;left<right;left--)
{
if(s[left]==' ')
{
s[right]='0';
s[right-1]='2';
s[right-2]='%';
right-=3;
}
else{
s[right--]=s[left];
}
}
return s;
}
};
总结
● 151.翻转字符串里的单词
题目描述
给你一个字符串 s
,请你反转字符串中 单词 的顺序。
单词 是由非空格字符组成的字符串。s
中使用至少一个空格将字符串中的 单词 分隔开。
返回 单词 顺序颠倒且 单词 之间用单个空格连接的结果字符串。
**注意:**输入字符串 s
中可能会存在前导空格、尾随空格或者单词间的多个空格。返回的结果字符串中,单词间应当仅用单个空格分隔,且不包含任何额外的空格。
示例 1:
输入:s = "the sky is blue"
输出:"blue is sky the"
解题思路
- 移除多余空格
- 将整个字符串反转
- 将每个单词反转
代码实现
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]);
}
}
//创建一个函数,删除字符串单词间多余空格
void removespace(string &s){
int slow=0,fast=0;
for(;fast<s.size();fast++)
{
if(s[fast]!=' ')
{
if(slow!=0)
{
s[slow++]=' ';//给单词之间加空格
}
while(fast<s.size()&&s[fast]!=' ')
{
s[slow++]=s[fast++];//将快指针指向的有效字符往慢指针里面写
}
}
}
s.resize(slow);//截断slow后面的字符串
}
string reverseWords(string s) {
removespace(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;
}
};
总结
函数形参用引用方式写,否则结果并未修改实参
反转字符串用双指针swap即可。
● 剑指Offer58-II.左旋转字符串
题目描述
字符串的左旋转操作是把字符串前面的若干个字符转移到字符串的尾部。请定义一个函数实现字符串左旋转操作的功能。比如,输入字符串"abcdefg"和数字2,该函数将返回左旋转两位得到的结果"cdefgab"。
示例 1:
输入: s = "abcdefg", k = 2
输出: "cdefgab"
解题思路
创建一个新的字符串。将原字符串分为两段,先将前n-1个字符写入result的末尾。然后将后半截的字符写入result的前半段。
代码实现
class Solution {
public:
string reverseLeftWords(string s, int n) {
string result;
int len=s.size();
result.resize(len);
for(int i=0;i<=n-1;i++)
{
result[len-n+i]=s[i];
}
for(int i=n,j=0;i<len;i++,j++)
{
result[j]=s[i];
}
return result;
}
};
总结
总算写出了一遍ac的代码。没有在原字符串上操作,需要额外创建一个result字符串,然后按要求往里面写。
空间复杂度O(n)
注意点在与原字符串截断的下标,画图可以更准确看出来下标如何变化。