344.反转字符串
题目
编写一个函数,其作用是将输入的字符串反转过来。输入字符串以字符数组 s 的形式给出。
不要给另外的数组分配额外的空间,你必须原地修改输入数组、使用 O(1) 的额外空间解决这一问题。
示例 1:
输入:s = [“h”,“e”,“l”,“l”,“o”]
输出:[“o”,“l”,“l”,“e”,“h”]
示例 2:
输入:s = [“H”,“a”,“n”,“n”,“a”,“h”]
输出:[“h”,“a”,“n”,“n”,“a”,“H”]
题解
这道题直接双指针,前后交换
class Solution {
public:
void reverseString(vector<char>& s) {
//采用双指针,从最左和最右交换
int i = 0, j = s.size() - 1;
while(i < j){
swap(s[i],s[j]);
i++;
j--;
}
}
};
541.反转字符串||
题目
给定一个字符串 s 和一个整数 k,从字符串开头算起,每计数至 2k 个字符,就反转这 2k 字符中的前 k 个字符。
如果剩余字符少于 k 个,则将剩余字符全部反转。
如果剩余字符小于 2k 但大于或等于 k 个,则反转前 k 个字符,其余字符保持原样。
示例 1:
输入:s = “abcdefg”, k = 2
输出:“bacdfeg”
示例 2:
输入:s = “abcd”, k = 2
输出:“bacd”
题解
//编程语言一般自己实现的库函数都是 “左闭右开” 的规则
class Solution {
public:
string reverseStr(string s, int k) {
//主要是对题目中条件的处理
/*如果剩余字符少于 k 个,则将剩余字符全部反转。
如果剩余字符小于 2k 但大于或等于 k 个,则反转前 k 个字符,其余字符保持原样。
*/
for(int i = 0; i < s.size();i += (2 * k) ){
//if(i + k ) <= s.size(),是对 “如果剩余字符小于 2k 但大于或等于 k 个,则反转前 k 个字符” 的处理
//if(i + k ) <= s.size(),也是对 “每计数至2k个字符,反转前 k 个字符” 的处理
if(i + k <= s.size()){
reverse(s.begin() + i, s.begin() + i + k );
}else{
//是对 “剩余字符少于k个的处理”
reverse(s.begin() + i , s.end());
}
}
return s;
}
};
剑指offer05.替换空格
题目
请实现一个函数,把字符串 s 中的每个空格替换成"%20"。
示例 1:
输入:s = “We are happy.”
输出:“We%20are%20happy.”
题解
1.我们可以借助一个辅助数组,用来存放替换后的新字符串
最后再借助双指针,给辅助数组赋值
class Solution {
public:
string replaceSpace(string s) {
//最容易想到,从前往后遍历,遇到空格之间替换,但是需要 辅助数组的支持【直接扩容辅助数组的长度】
//统计空格的数量,进行扩容
int count = 0;
for(int i = 0; i < s.size();i++){
if(s[i] == ' ') count++;
}
string result = s;
result.resize(count * 2 + s.size());
int j = 0;
//利用双指针进行新数组的生成
for(int i = 0;i < s.size();i++){
if(s[i] != ' '){
result[j] = s[i];
j++;
}
else{
result[j] = '%';
j++;
result[j] = '2';
j++;
result[j] = '0';;
j++;
}
}
return result;
}
};
2.不借助辅助数组,直接进行原地替换时
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++;
}
s.resize(count * 2 + s.size()); //此时长度刚好够替换后的字符串长度【注意是 2 * count + size 因为空格本身就占一个长度】
//原地替换
//这里从前往后替换的话,遇到空格,空格后面的字符就要向后移动,处理麻烦
//从后往前替换时,从后向前填充元素,避免了从前先后填充元素要来的 每次添加元素都要将添加元素之后的所有元素向后移动。
int i = oldSize - 1, j = s.size() - 1;
while(i >= 0){
if(s[i] != ' '){
s[j] = s[i];
i--;
j--;
}else{
s[j] = '0';
j--;
s[j] = '2';
j--;
s[j] = '%';
j--;
i--;
}
}
return s;
}
};
剑指Offer58-II.左旋转字符串
题目
字符串的左旋转操作是把字符串前面的若干个字符转移到字符串的尾部。请定义一个函数实现字符串左旋转操作的功能。比如,输入字符串"abcdefg"和数字2,该函数将返回左旋转两位得到的结果"cdefgab"。
示例 1:
输入: s = “abcdefg”, k = 2
输出: “cdefgab”
示例 2:
输入: s = “lrloseumgh”, k = 6
输出: “umghlrlose”
题解
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]);
}
}
string reverseLeftWords(string s, int n) {
//1.翻转整个字符串
reverse(s,0,s.size() - 1);
//翻转前size - n个字符
reverse(s,0,s.size() - n - 1);
//翻转剩余字符
reverse(s,s.size() - n ,s.size() - 1);
return s;
}
};