题目链接:P344.反转字符串
代码随想录讲解
题目描述:
编写一个函数,其作用是将输入的字符串反转过来。输入字符串以字符数组 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"]
提示:
1 <= s.length <= 105
s[i]
都是 ASCII 码表中的可打印字符思路:
利用一个交换值进行交换就好
代码:
class Solution {
public:
void reverseString(vector<char>& s) {
int left = 0;
int right = s.size()-1;
while(left < right){
char tmp;
tmp = s[left];
s[left] = s[right];
s[right] = tmp;
left++;
right--;
}
}
};
题目链接:P541. 反转字符串II
代码随想录讲解
题目描述:
给定一个字符串 s
和一个整数 k
,从字符串开头算起,每计数至 2k
个字符,就反转这 2k
字符中的前 k
个字符。
k
个,则将剩余字符全部反转。2k
但大于或等于 k
个,则反转前 k
个字符,其余字符保持原样。示例 1:
输入:s = "abcdefg", k = 2
输出:"bacdfeg"
示例 2:
输入:s = "abcd", k = 2
输出:"bacd"
提示:
1 <= s.length <= 104
s
仅由小写英文组成1 <= k <= 104
思路:
可以直接调用reverse方法进行反转,就是要注意一下for循环的循环条件,以及里面的判断条件。for循环中 i = i + 2*k,然后里面的判断,当剩余字符小于k个,即s.size() - i < k 时,剩余字符全部反转,其他时候则只反转前k个
代码:
class Solution {
public:
string reverseStr(string s, int k) {
for(int i = 0;i<s.size();i = i + 2*k){
if(s.size() - i < k){
reverse(s.begin()+i,s.end());
}else{
reverse(s.begin()+i,s.begin()+i+k);
}
}
return s;
}
};
题目链接:剑指Offer 05.替换空格
代码随想录讲解
题目描述:
假定一段路径记作字符串 path
,其中以 “.
” 作为分隔符。现需将路径加密,加密方法为将 path
中的分隔符替换为空格 "
",请返回加密后的字符串。
示例 1:
输入:path = "a.aef.qerf.bb"
输出:"a aef qerf bb"
限制:
0 <= path.length <= 10000
思路:
循环遍历替换就好
代码:
假定一段路径记作字符串 path,其中以 "." 作为分隔符。现需将路径加密,加密方法为将 path 中的分隔符替换为空格 " ",请返回加密后的字符串。
示例 1:
输入:path = "a.aef.qerf.bb"
输出:"a aef qerf bb"
限制:
0 <= path.length <= 10000
其实这题leetcode修改过了,原来的题目应该是这样的
请实现一个函数,把字符串 s 中的每个空格替换成"%20"。
示例 1: 输入:s = “We are happy.”
输出:“We%20are%20happy.”
那么如何做这题并且尽量的减少内存开销(不申请新数组)
思路:
因为 ' '
和'20%'
的大小是不一样的,所以要先对数组进行扩容,统计字符串中空格的字数,然后再对size进行加count *2 。然后从后向前替换空格,也就是双指针法,过程如下:
i指向新长度的末尾,j指向旧长度的末尾。
代码:
class Solution {
public:
string replaceSpace(string s) {
int count = 0; // 统计空格的个数
int sOldSize = s.size();
for (int i = 0; i < s.size(); i++) {
if (s[i] == ' ') {
count++;
}
}
// 扩充字符串s的大小,也就是每个空格替换成"%20"之后的大小
s.resize(s.size() + count * 2);
int sNewSize = s.size();
// 从后先前将空格替换为"%20"
for (int i = sNewSize - 1, j = sOldSize - 1; j < i; i--, j--) {
if (s[j] != ' ') {
s[i] = s[j];
} else {
s[i] = '0';
s[i - 1] = '2';
s[i - 2] = '%';
i -= 2;
}
}
return s;
}
};
题目描述:P151.翻转字符串里的单词
代码随想录讲解
题目描述:
给你一个字符串 s
,请你反转字符串中 单词 的顺序。
单词 是由非空格字符组成的字符串。s
中使用至少一个空格将字符串中的 单词 分隔开。
返回 单词 顺序颠倒且 单词 之间用单个空格连接的结果字符串。
**注意:**输入字符串 s
中可能会存在前导空格、尾随空格或者单词间的多个空格。返回的结果字符串中,单词间应当仅用单个空格分隔,且不包含任何额外的空格。
示例 1:
输入:s = "the sky is blue"
输出:"blue is sky the"
示例 2:
输入:s = " hello world "
输出:"world hello"
解释:反转后的字符串中不能存在前导空格和尾随空格。
示例 3:
输入:s = "a good example"
输出:"example good a"
解释:如果两个单词间有多余的空格,反转后的字符串需要将单词间的空格减少到仅有一个。
提示:
1 <= s.length <= 104
s
包含英文大小写字母、数字和空格 ' '
s
中 至少存在一个 单词**进阶:**如果字符串在你使用的编程语言中是一种可变数据类型,请尝试使用 O(1)
额外空间复杂度的 原地 解法。
思路:
第一步:先对字符串的多余空格进行删除,采用双指针法删除多余空格
void removeExtraSpaces(string& s) {
int slowIndex = 0, fastIndex = 0; // 定义快指针,慢指针
// 去掉字符串前面的空格
while (s.size() > 0 && fastIndex < s.size() && s[fastIndex] == ' ') {
fastIndex++;
}
for (; fastIndex < s.size(); fastIndex++) {
// 去掉字符串中间部分的冗余空格
if (fastIndex - 1 > 0
&& s[fastIndex - 1] == s[fastIndex]
&& s[fastIndex] == ' ') {
continue;
} else {
s[slowIndex++] = s[fastIndex];
}
}
if (slowIndex - 1 > 0 && s[slowIndex - 1] == ' ') { // 去掉字符串末尾的空格
s.resize(slowIndex - 1);
} else {
s.resize(slowIndex); // 重新设置字符串大小
}
}
第二步:然后对整个字符串进行反转
第三步:对每个单词进行反转
代码:
class Solution {
public:
//先去除多余的空格
void removeSpace(string& s){
int solw =0 ,fast =0;
//去掉开头的空格
while(s.size()>0 && fast<s.size() && s[fast] ==' '){
fast++;
}
for(;fast<s.size();fast++){
if(fast -1>0 && s[fast -1] == s[fast] && s[fast] ==' '){
continue;
}else{
s[solw] = s[fast];
solw++;
}
}
if(solw -1 >0 && s[solw - 1] ==' '){
s.resize(solw - 1);
}else{
s.resize(solw);
}
}
//反转
void reserve(string &s,int start,int end){
for (int i = start, j = end; i < j; i++, j--) {
swap(s[i], s[j]);
}
}
string reverseWords(string s) {
removeSpace(s);
reserve(s,0,s.size()-1);
int start = 0;
for(int i = 1;i<=s.size();i++){
if(i == s.size() || s[i] == ' '){
reserve(s,start,i-1);
start = i +1;
}
}
return s;
}
};
题目链接:剑指Offer58-II.左旋转字符串
代码随想录链接
题目描述:
某公司门禁密码使用动态口令技术。初始密码为字符串 password
,密码更新均遵循以下步骤:
target
password
前 target
个字符按原顺序移动至字符串末尾请返回更新后的密码字符串。
示例 1:
输入: password = "s3cur1tyC0d3", target = 4
输出: "r1tyC0d3s3cu"
示例 2:
输入: password = "lrloseumgh", target = 6
输出: "umghlrlose"
提示:
1 <= target < password.length <= 10000
思路:
我自己的思路:
先将数组扩容一位,然后将第一个元素拿到最后一个元素位置,再让元素不断的去覆盖上去,这样就能实现。耗时太久
代码:
class Solution {
public:
string dynamicPassword(string password, int target) {
password.resize(password.size()+1);
while(target--){
password[password.size()-1] = password[0];
for(int j = 0;j<password.size()-1;j++){
password[j] = password[j+1];
}
}
password.resize(password.size()-1);
return password;
}
};
代码随想录的思路:
先反转target前的字符,再反转target后的字符,再将整个字符反转。
代码:
class Solution {
public:
string dynamicPassword(string password, int target) {
reverse(password.begin(),password.begin()+target);
reverse(password.begin()+target,password.end());
reverse(password.begin(),password.end());
return password;
}
};