代码随想录训练营|第四章 字符串part02

力扣151 反转字符串中的单词

题目链接/文章讲解/视频讲解:代码随想录

思路:这道题可以分为几个小步骤解决,首先删掉额外的空格,可以依次删除开头的空格,中间多余的空格,结尾的空格。更简单的方法是遇到空格就删掉,再在除了第一个单词以外,每个单词前面添加一个空格。其次反转所有元素,然后以空格为标志反转每一个单词。

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 reverseExtraSpace(string &s){
        int slow = 0;
        for(int i = 0; i < s.size(); i++){
            if(s[i] != ' '){
                if(slow != 0){
                    s[slow++] = ' ';
                }
                while(i < s.size() && s[i] != ' '){
                    s[slow++] = s[i++];
                }
            }
        }
        s.resize(slow);
    }
    string reverseWords(string s) {
        reverseExtraSpace(s);
        reverse(s, 0, s.size() - 1);
        int start = 0;
        for(int i = 0; i <= s.size(); ++i){
            if(s[i] == ' ' || i == s.size()){
                reverse(s, start, i-1);
                start = i + 1;
            }
        }
        return s;
    }
};

这里有一个小问题,通常在for循环处理数组时,i < s.size()即可,但是这里判断最后一个单词时,因为反转的end值是i-1,所以需要i的值取到s.size(),这里就要加一个等号。也可以不加等号分开写。

string reverseWords(string s) {
        reverseExtraSpace(s);
        reverse(s, 0, s.size() - 1);
        int start = 0;
        for(int i = 0; i < s.size(); ++i){
            if(s[i] == ' '){
                reverse(s, start, i-1);
                start = i + 1;
            }
            if(i == s.size() - 1){
                reverse(s, start, i);
            }
        }
        return s;
    }

 卡码网55 右旋字符串

题目链接/文章讲解:

代码随想录

思路:一开始的想法是给字符串前面插入k个0,然后与末尾的k个字符交换。看讲解后,将字符串整体翻转,然后根据k值将字符串分为两段分别反转。

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

int main(){
    int k;
    string s;
    cin >> k >> s;
    int len = s.size();
    reverse(s.begin(), s.end());
    reverse(s.begin(), s.begin() + k);
    reverse(s.begin() + k, s.end());
    
    cout << s << endl;
}

这里遇到了一些问题:

1. 为什么是s.begin()+k,而不是直接用k

reverse 函数需要两个迭代器作为参数,而不是一个迭代器和一个整数。

2. 为什么第二个反转是reverse(s.begin(), s.begin() + k);而不是 reverse(s.begin(), s.begin() + k-1); 

 

  1. 迭代器范围:在C++中,当我们使用迭代器指定一个范围时,通常遵循"左闭右开"的原则。这意味着起始迭代器指向我们想要包含的第一个元素,而结束迭代器指向我们想要包含的最后一个元素之后的位置。

  2. reverse 函数的工作方式:reverse 函数反转[first, last)范围内的元素,其中 last 是要反转的最后一个元素之后的位置。

  3. 举个例子:如果我们想反转字符串 “abcde” 的前三个字符,我们需要:

    • 开始位置:指向 ‘a’(第一个字符)
    • 结束位置:指向 ‘d’(第四个字符,即第三个字符之后)
  4. 在代码中体现:

    • s.begin() 指向第一个字符
    • s.begin() + k 指向第 k+1 个字符,正好是我们想要反转的最后一个字符之后的位置

如果我们使用 s.begin() + k-1,那么我们实际上会少反转一个字符。例如,如果 k = 3,那么我们只会反转前两个字符,而不是前三个。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值