当前位置:网站首页>Leetcode——344. 反转字符串/541. 反转字符串 II/151. 颠倒字符串中的单词/剑指 Offer 58 - II. 左旋转字符串

Leetcode——344. 反转字符串/541. 反转字符串 II/151. 颠倒字符串中的单词/剑指 Offer 58 - II. 左旋转字符串

2022-07-07 12:15:00 styfish

概述

344. 反转字符串

541. 反转字符串 II

151. 颠倒字符串中的单词

剑指 Offer 58 - II. 左旋转字符串

  • 这几题都和字符串翻转有关

分析

344

  • 题目要求原地修改,可以考虑使用双指针+swap()函数实现

    实际上,内置函数reverse()就是通过这个实现;

541

  • 这题,我们利用reverse()模拟一下操作即可

151

  • 个人认为这是一个技巧题,要能想到使用多次反转的思路
    • 首先翻转整个字符串
    • 然后在对每个单词进行一次翻转,即可实现最终效果

这里有一个难点在于,第二次翻转如何确定一个单词进行翻转

**剑指 Offer 58 **

  • 这题,个人认为也算一个技巧题,和151一样,使用多次翻转的思路

思路

151

第二次翻转如何确定一个单词?

  • 我们容易想到利用空格来区分单词,但是根据题目说明:存在前导空格、尾随空格和单词间多个空格,所以这里还是需要仔细处理一下
  • 首先我们第一翻转后,题目中的三种特殊空格情况仍然存在,我们可以分情况处理:
    • 对于前导空格和单词间的多个空格,我们可以每次确定一个字母后,再去寻找该字母所在的单词
    • 而通常也是利用空格来区分单词。但是考虑到末尾可能不存在空格,就无法区分最后一个单词,于是为了统一操作,我们可以在末尾手动添加一个空格

代码

344

class Solution {
    
public:
    void reverseString(vector<char>& s) {
    
        int left = 0, right = s.size() - 1;		// 双指针
        while (left < right) {
    
            swap(s[left++], s[right--]);		// STL swap() 
        }
    }
};

541

class Solution {
    
public:
    string reverseStr(string s, int k) {
    
        for (int i = 0; i < s.size();i += (2 * k)) {
    		// 模拟操作
            if (i + k <= s.size()) {
    
                reverse(s.begin() + i, s.begin() + i + k );
                continue;
            }
            reverse(s.begin() + i, s.begin() + s.size());
        }
        return s;
    }
};

151

class Solution {
    
public:
    string reverseWords(string s) {
    
        reverse(s.begin(), s.end());        // 先翻转所有字符

        s.push_back(' ');       // 统一操作,在末尾添加空格
        for(int i = 0; i < s.size(); ++i) {
    
            if (s[i] != ' ') {
    		// 直到出现第一个字母,可以处理前导空格和单词间多个空格
                int j = i + 1;
                for (; j < s.size(); ++j) {
    
                    if (s[j] == ' ') {
    		// 遇到一个空格,可以确定该单词的前后位置索引了
                        reverse(s.begin() + i, s.begin() + j);      // 再翻转单个单词
                        i = j;  		// 继续处理 
                        break;			
                    }
                }
            }
        }
        // 去除多余空格。利用双指针法,向前移动
        int i = 0, j = 0;
        for(;j < s.size(); ++j) {
    
            if (s[j] != ' ')
                s[i++] = s[j];
            else if(s[j] == ' ' && i > 0 && s[i - 1] != ' ')
                s[i++] = ' ';

        }
        s.resize(i - 1);     // 缩小string,留下实际有用的部分
        return s;
    }
};

小技巧:

直接利用resize()来删除末尾的内存

剑指 Offer 58

class Solution {
    
public:
    string reverseLeftWords(string s, int n) {
    
        reverse(s.begin(), s.end());		// 第一次翻转整个字符串

        int size = s.size();
        // 下面两个翻转是为了恢复正常的顺序,如果不懂可以手动模拟一下
        reverse(s.begin(), s.begin() + size - n);	
        reverse(s.begin() + size - n, s.end());

        return s;
    }
};
原网站

版权声明
本文为[styfish]所创,转载请带上原文链接,感谢
https://blog.csdn.net/qq_40725780/article/details/124943395