代码随想录 (字符串1) | 反转字符串&反转字符串II &替换数字&翻转字符串里的单词&右旋转字符串

部分反转字符串,
1.先将字符串整体反转(局部字符串的位置是对的了,字符串中的字符顺序不是反的了)
2. 然后再局部反转就可以实现 (将局部字符串反转为正常的字符串)

344.反转字符串

反转字符串中的单词,将右边的几个字符放到字符串的左边都可以这么操作

题目链接/文章讲解/视频讲解

class Solution {
public:
    void reverseString(vector<char>& s) {
        int left = 0;
        int right = s.size() -1;
        //双指针交换,思路有了很简单
        while(left < right) {
            swap(s[left],s[right]);
            left ++;
            right --;
        }
    }
};
//代码简化
class Solution {
public:
    void reverseString(vector<char>& s) {
        for (int i = 0, j = s.size() - 1; i < s.size()/2; i++, j--) {
            swap(s[i],s[j]);
        }
    }
};

541. 反转字符串II

建议:本题又进阶了,自己先去独立做一做,然后在看题解,对代码技巧会有很深的体会。

题目链接/文章讲解/视频讲解
注意自定义反转字符串的区间定义

class Solution {
public:
    // 注意:这里是左闭右闭区间,因为是数组下标,所以end需要减1
    string reverseStr(string& s, int start, int end) {
        for(int i = start , j = end - 1 ; i < j; i ++, j--) {
            swap(s[i],s[j]);
        }
        return s;
    }
    string reverseStr(string s, int k) {
        int temp_size = 0;
        int i = 0;
        for(int i = 0; i < s.size(); i += (2*k)) {
            if(s.size() >= i + k ){
                // 注意:这里是左闭右闭区间
                s = reverseStr(s, i, i + k);
            } else {
                //剩余小于k,将剩余全部反转
                s = reverseStr(s, i, s.size());
            }
        }

        return s;
        
    }
};
//使用C++ reverse 函数
class Solution {
public:
    string reverseStr(string s, int k) {
        int temp_size = 0;
        int i = 0;
        for(int i = 0; i < s.size(); i += (2*k)) {
            if(s.size() >= i + k ){
                // 注意:这里是左闭右闭区间
                reverse(s.begin() + i, s.begin() + i + k);
            } else {
                //剩余小于k,将剩余全部反转
                reverse(s.begin() + i, s.end());
            }
        }

        return s;
    }
};

卡码网:54.替换数字

建议:对于线性数据结构,填充或者删除,后序处理会高效的多。好好体会一下。
题目链接/文章讲解

#include <iostream>
using namespace std;
#include <string>

string replace_number(string& str, string& replace_str) {
    int count = 0; 
    int old_size = str.size();
    for(int i = 0; i < str.size(); i ++) {
        if(str[i] >= '0' && str[i] <= '9') {
            count ++;
        }
    }
    //被替换的字符也占一个位置,所以这里要-1
    str.resize(str.size() + (replace_str.length() - 1) * count);

    for(int i = old_size - 1, j = str.size() - 1; i >= 0;){
        if(str[i] < '0'  || str[i] > '9') {
            str[j --] = str[i --];
        } else {
            //反向将替换字符串替换
            for(int t = replace_str.size() - 1; t >= 0; t --) {
                str[j--] = replace_str[t];
            }
            i--;// 替换的那个字符对应的原字符所以i--
        }
    }
    return str;
}
int main() {

    string str = "123abc123ab123";
    string replace_str = "number";
    cout << str << endl;

    replace_number(str, replace_str);
    cout << str << endl;
    string replace_str1 = "AA";
    string str1 = "123abc123ab123";
    replace_number(str1, replace_str1);
    cout << str1 << endl;
    return 0;
}

151.翻转字符串里的单词

建议:这道题目基本把 刚刚做过的字符串操作 都覆盖了,不过就算知道解题思路,本题代码并不容易写,要多练一练。

题目链接/文章讲解/视频讲解

class Solution {
public:
    string delete_empty(string& s) {
        int count = 0;
        int slow = 0;
        int fast = 0;
        while(s.size() > 0 && s[fast] == ' '&& fast < s.size()){
            fast ++;
        }

        for(; fast < s.size() ;) {
            //如果是个字符,直接加入进来,
            // 如果是个空格,空格后必须是个字符,这个空格才保留,这样末尾就不会有空格
            if(s[fast] != ' ' || (s[fast] == ' ' && fast + 1 < s.size() && s[fast + 1] != ' ')) {
                s[slow ++] = s[fast++];
                
            } else {
                fast ++;
            }
        }

        //slow 是下标是从0开始的,所以这里resize为slow
        s.resize(slow);
        return s;
    }

    string reverseWords(string s) {
        delete_empty(s);
        reverse(s.begin(),s.end() );
        int slow = 0;
        //因为 reverse 库的区间是[) 所以 这里需要遍历到 == size()(s.end()) 才能将最后的单词反转
        for(int i = 0; i <= s.size(); i ++) {
            // 这里的i == s.size() 必须写在前面,s[i] 获取有可能越界
            if(i == s.size() || s[i] == ' ') {
                reverse(s.begin() + slow, s.begin() + i);
                slow = i + 1;
            }

        }
        return s;
    }
};

//使用临时字符串辅助从后往前的双指针法的代码
string reverseMessage1(string message) {
    if(message.empty()) {
        return "";
    }
    string result = "";
    int left = message.size() - 1;
    int length = 0;
    cout << left << endl;
    for(; left >= 0; left --) {
        cout << left << endl;
        cout << "message[left]" << message[left] << endl;
        if(message[left] != ' ') {
            length ++;
        } else {
            if(length != 0) {
            	//这里在注意要left要+1 ,因为此时left上的字符为空格,需要取他后边的
                result.append(message.substr(left + 1, length));
                result.push_back(' ');
                length = 0;
            }
        }
    }

//如果length != 0 说明原字符串中第一个字符不是空格,所以需要将原数据的第一段数据添加进来
    if(length != 0) {
        result.append(message.substr(left + 1, length)); 
    }

    //如果result的最后一个字符是空格需要去掉
    if(!result.empty() && result.back() == ' ') {
        result.pop_back();
    }

    return result;
}

卡码网:55.右旋转字符串

建议:题解中的解法如果没接触过的话,应该会想不到

题目链接/文章讲解

#include <iostream>
#include <string>
#include <algorithm>
using namespace std;

string right_recerse(string &str, int num) {
    //先整体反转
    reverse(str.begin(), str.end());
    
    //局部反转
    //反转变前边的原后边的部分
    reverse(str.begin(), str.begin() + num);
    //反转原前面的部分
    reverse(str.begin() + num,str.end());

    return str;
}
int main() {
    string str = "12345abc";
    cout << str << endl;
    cout << right_recerse(str,3) << endl;
}
  • 9
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值