@代码随想录算法训练营第8天 | LeetCode344.反转字符串,541. 反转字符串II,剑指Offer 05.替换空格 151.翻转字符串里的单词,剑指Offer58-II.左旋转字符串
344.反转字符串
第一遍读题思考(五分钟内,如果没有思路就写暴力解法思路,暴力解法思路也不清晰就写无
不能开辟额外的空间,那直接前后双指针法不就可以了吗。
代码随想录解法思路
一样的想法,没什么额外的。就是拓展了一下swap的底层实现逻辑。
第一种很好理解。
第二种其实是位运算的结论,0与任何数异或都是复制,1与任何数异或都是反转那个数。所以先让要交换的两个数去异或就可以获得两个数各个位之间的关系mask(0相同或者1相异)。然后用这个mask再去跟两个数异或,0的位置相同也是直接copy下来,1的位置不同就取反。可参照下图说明。
c++代码具体实现注意事项
for循环里可以用两个条件判断,可以学习一下下面的代码写法,看着更简洁。
class Solution {
public:
void reverseString(vector<char>& s) {
for(int i=0,j=s.size()-1;i<j;i++,j--){
swap(s[i],s[j]);
}
}
};
学习时长
10分钟
541. 反转字符串II
第一遍读题思考(五分钟内,如果没有思路就写暴力解法思路,暴力解法思路也不清晰就写无
感觉没什么特殊的地方,就按照题目的要求用循环去遍历好像就可以。
代码随想录解法思路
巧用for循环的前进条件。
c++代码具体实现注意事项
基本没什么需要注意的,唯一一个点是传参的方式,如果不加&,那么对主函数里的s不会有改变。
class Solution {
public:
void reverseIn(string &s, int start, int end){
for(int i=start,j=end;i<j;i++,j--){
swap(s[i],s[j]);
}
}
string reverseStr(string s, int k) {
for(int i=0;i<s.size();i+=(2*k)){
if(i+k-1<s.size()){
reverseIn(s,i,i+k-1);
}
else{
reverseIn(s,i,s.size()-1);
}
}
return s;
}
};
学习时长
20分钟
剑指Offer 05.替换空格
第一遍读题思考(五分钟内,如果没有思路就写暴力解法思路,暴力解法思路也不清晰就写无
暴力法,直接for循环遍历。
代码随想录解法思路
对题目理解有偏差,把空格换成%20并不是简单的复制操作,这是个字符串而不是数组。严格意义来讲这个不叫替换而是填充字符串。
c++代码具体实现注意事项
注意循环的终止条件
class Solution {
public:
string replaceSpace(string s) {
int count{0};
for(int i=0;i<s.size();i++){
if(s[i]==' '){
count++;
}
}
s.resize(s.size()+2*count);
// i == j means that there is no more space.
for(int i=s.size()-1,j=(s.size()-1-2*count);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;
}
};
学习时长
20分钟
151 翻转字符串里的单词
第一遍读题思考(五分钟内,如果没有思路就写暴力解法思路,暴力解法思路也不清晰就写无
读题的时候脑子比较乱,没有思路。
代码随想录解法思路
先反转所有字符,然后逐个单词反转。记录空格数量,遍历整个字符串,后值赋给前值。注意用快慢指针剔除多余空格,快指针遇到空格则慢指针不动,快指针继续直到遇到非空格,然后快指针赋值给慢指针并且同时加加,下一次快指针再次遇到非空格的时候先把慢指针赋值为空格,再进行赋值操作,直到快指针、遍历结束再用slow的值resize字符串即可。
c++代码具体实现注意事项
class Solution {
public:
string reverseWords(string s) {
reverse(s.begin(), s.end());
int slow{0};
for(int fast=0;fast<s.size();fast++){
if(s[fast]!=' '){
if(slow!=0)s[slow++]=' ';
while(s[fast]!=' ' && fast<s.size()){
s[slow++]=s[fast++];
}
}
}
s.resize(slow);
// reverse each word
int j=0;
for(int i=0;i<s.size();i++){
if(s[i]==' '){
reverse(s.begin()+j,s.begin()+i);
j=i+1;
}
else if(i==s.size()-1){
reverse(s.begin()+j,s.end());
}
}
return s;
}
};
学习时长
40分钟
剑指Offer58-II.左旋转字符串
第一遍读题思考(五分钟内,如果没有思路就写暴力解法思路,暴力解法思路也不清晰就写无
三次反转,好简单
代码随想录解法思路没什么说的
c++代码具体实现注意事项
class Solution {
public:
string reverseLeftWords(string s, int n) {
reverse(s.begin(), s.end());
reverse(s.begin(), s.end()-n);
reverse(s.end()-n, s.end());
return s;
}
};
学习时长
10分钟