代码随想录算法训练营第八天|344.反转字符串、541.反转字符串II、151.翻转字符串里的单词

344.反转字符串

344. 反转字符串 - 力扣(LeetCode)icon-default.png?t=N7T8https://leetcode.cn/problems/reverse-string/解题思路:

不知道大家是否还记得在前几篇文章中我们经常提到的双指针法,并且曾经使用双指针的方法解决过反转链表这道题,但是反转字符串这个题要比反转链表简单得多,因为他是数组的结构,元素之间的位置是连续的。

具体思路就是我们先设置两个指针一个放在数组的开头一个放在数组的结尾,两个指针向中间移动,并对所指向的元素做一个交换,直到他们指向同一个元素。这里数组的元素个数是奇数还是偶数没有关系。

具体代码如下:

class Solution {
public:
    void reverseString(vector<char>& s) {
        int left = 0;
        int right = s.size() - 1;//定义两个指针
        int temp = 0;
        while(left <= right){
            temp = s[left];
            s[left] = s[right];
            s[right] = temp;//交换两个指针指向的元素
            left++;
            right--;//将两个指针向中间靠拢
        } 
    }
};

541.反转字符串II

 解题思路:

本题的没有什么具体的算法,就是模拟题目要求的一个过程,在我们遍历一个字符串的过程中通常喜欢让i每循环一次加1,但是在本题中,它是每2k使其中的一个k反转,所以我们遍历的时候应该每循环一次让i加2k,这样就不用去专门找每到2k的条件了,如果字符串的长度够,那么每循环一个2k就将字符串从i 到 i+k 个字符反转,如果长度不足2k但是足k就将i 到i+k 个字符反转,如果长度不足k,就将i到字符串结尾的字符反转。

具体代码如下:

class Solution {
public:
    string reverseStr(string s, int k) {
        for(int i = 0;i < s.size();i += (2 * k)){//2k个2k个的遍历
            if(i + k <= s.size()){//当剩余的字符的个数足够k个,就将这k个反转
                reverse(s.begin() + i,s.begin() + i + k);//C++中的反转字符串的函数
            }else{
            reverse(s.begin() + i,s.end());//如果不足k个就将剩余的这些字符全部反转
            }
        }
        return s;
    }
};

151.翻转字符串里的单词

151. 反转字符串中的单词 - 力扣(LeetCode)icon-default.png?t=N7T8https://leetcode.cn/problems/reverse-words-in-a-string/description/解题思路:

这个题我们可以分为三步来做,一是清除除每个单词之间需要的一个空格外其他所有空格,二是将字符串整体反转,三是将字符串中的每个单词反转。

在这三步中,比较复杂的是清除空格那一步,再清楚空格时,我们可以选择用双指针法,快指针负责遍历整个字符串,慢指针在它遍历到非空格元素时将此元素存起来,当然如果在快指针遍历到非空格元素时并且此时慢指针不为初始值,就另加一个空格存入慢指针(此步相当于是慢遍历到了两个单词之间并给他加了一个空格使它和快指针同步)。其他两步就是常规写法。

具体代码如下:

class Solution {
public:
    void reverse(string& s,int start,int end){//反转字符串的函数
        int i = start;
        int j = end;
        while(i < j){
            swap(s[i],s[j]);
            i++;
            j--;
        }
    }
    void remove(string& s){
        int slow = 0;
        for(int fast = 0;fast < s.size();fast++){
            if(s[fast] != ' '){//因为除了开头的单词,每个单词之前都有一个空格
                if(slow != 0){//用双指针的方法,只要fast指向的字符不是空格,并且这个字符也不是第一个单词的第一个字符,将slow的向后移一位并在这一位上放上一个空格
                    s[slow++] = ' ';
                }
                while(fast < s.size() && s[fast] != ' '){//只要fast指向的字符不是空格,并且fast小于字符串的长度,就将fast指向的每一位不是空格的字符放入slow中
                    s[slow++] = s[fast++];
                }
            }
        }
        s.resize(slow);
    }
    string reverseWords(string s) {
        remove(s);
        reverse(s,0,s.size() - 1);
        int start = 0; 
       for(int i = 0;i <= s.size();i++){
           if(i == s.size() || s[i] == ' '){  
               reverse(s,start,i - 1);//因为i的位置是空格,所以从start到i - 1进行反转,下一次从i+1开始
               start = i + 1 ;
           }
       }
       return s;
    }
};

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值