随想录训练营7/60 | LC 344.反转字符串 ;LC 541. 反转字符串II;剑指Offer 05.替换空格 ;LC 151.翻转字符串里的单词 ;剑指Offer58-II.左旋转字符串

LC 344.反转字符串

题目链接LC 344.反转字符串
思路:前提是不使用额外的空间。因此也是用双指针法,从开头l和结尾r开始遍历,交换指针对应的值。终止条件为l>=r(当为偶数个时,遍历到最后l>r;当为奇数个时,遍历到最后l==r结束)。
代码

class Solution {
public:
    void reverseString(vector<char>& s) {
        int l = 0;
        int r = s.size() - 1;
        while(l<r){
            char temp = s[l];
            s[l] = s[r];
            s[r] = temp;
            //以上三句可简化为
            // swap(s[l], s[r]);
            ++l;
            --r;
        }
    }
};

LC 541. 反转字符串II

题目链接LC 541. 反转字符串II
思路:遍历的时候每次走2k步,然后每次反转2k中的前k个。重点是最后剩余的字符数目少于K,与大于等于K时的区别,可以在每次迭代时进行判断。
代码

class Solution {
public:
    string reverseStr(string s, int k) {
        if(s.size()<=1)return s;
        for(int i=0; i<s.size(); i+=2*k){
            if(i+k<=s.size()){//实际时i+k-1<=s.size()-1,都看得下标值
            reverse(s.begin()+i, s.begin()+(i+k));//C++自带的函数,输入是字符串的地址,且不是对输入的最后字符进行反转,而是其前一个s.begin()+(i+k)-1
            }
            else{
                reverse(s.begin()+i, s.end());
            }
        }
        return s;
    }
};

剑指Offer 05.替换空格

题目链接剑指Offer 05.替换空格
思路
思路1:可以创建一个新的vector,遍历字符串,若遇到空格就将其变为‘%20‘插入vector中,若不为空格则将该值插入vector中。
思路2:为了不占用额外得空间,可以先遍历字符串找到空格的个数,然后延长字符串长度。双指针,一个指向就字符串末尾,一个指向新串末尾,从后向前遍历,若为空格就插入’%20‘,否则直接插入该值。
代码

class Solution {
public:
    //思路1
    // string replaceSpace(string s) {
    //     string temp;
    //     for(char i : s){
    //         if(i==' ')temp+="%20";
    //         else temp+=i;
    //     }
    //     return temp;
    // }
    //思路2
    string replaceSpace(string s) {
        int num = 0;
        for(char i : s){
            if(i==' ')++num;
        }
        if(num==0)return s;
        int l = s.size() - 1;//保存旧长度
        s.resize(s.size() + 2*num);//1变3(加2)
        int r = s.size() - 1;
        while(r!=l){
            if(s[l]!=' ')s[r] = s[l];
            else{
                s[r] = '0';
                --r;
                s[r] = '2';
                --r;
                s[r] = '%';
            }
            --r;
            --l;
        }
        return s;
    }
};

LC 151.翻转字符串里的单词

题目链接LC 151.翻转字符串里的单词
思路:分成三步,1先删除多余的空格;2反转整个字符串;3按空格反转单词
代码

class Solution {
public:
    //删除多余空格
    void removeExtraSpace(string &s){
        int num = 0;//统计删除多余空格后的字符转长度
        for(int i=0; i<s.size(); i++){
            //删除每个单词前面的空格
            if(s[i]!=' '){//可删除最前面的空格,找到不为空格的char
                //找单词末尾(下一个空格)
                while(i<s.size() && s[i]!=' '){
                    s[num] = s[i];
                    ++num;
                    ++i;
                }
                //若有空格或者到最后,则手动加空格(在单词末尾加上空格)
                s[num] = ' ';//不让s[num] = s[i],是因为s[i]可能溢出,这样每个单词后面都会有一个空格,返回时需要把最后一个空格删除
                num++;
            }
        }
        s.resize(num-1);//把最后的空格删除
    }

    string reverseWords(string s){
        //1删除多余空格
        removeExtraSpace(s);
        //2反转整个字符串
        reverse(s.begin(), s.end());
        //3每个单词进行反转
        int l = 0;
        for(int r=0; r<s.size(); r++){
            //若找到空格则反转开始到空格这段字符串
            //r指向单词的末尾后的空格,l指向单词的第一个字母
            if(s[r]==' '){
                reverse(s.begin()+l, s.begin()+r);
                l = r+1;
            }
            else if(r == s.size()-1){//到末尾时全部反转
                reverse(s.begin()+l, s.end());
            }
        }
        return s;
    }
};

剑指Offer58-II.左旋转字符串

题目链接剑指Offer58-II.左旋转字符串
思路:先反转局部再反转全局;或者先反转全局再反转局部,两者等价。先反转前k个字符组成的字符串和从k到最后的字符串,再反转全部字符串。
代码

class Solution {
public:
    //先局部再全局
    string reverseLeftWords(string s, int n) {
        //先反转前n个
        reverse(s.begin(), s.begin()+n);//旋转从0到n-1的字符串
        reverse(s.begin()+n, s.end());
        reverse(s.begin(), s.end());
        return s;
    }
};

------------------------------------额外题目---------------------------------

(以上为训练营每日任务,本部分为自己刷题进度)

LC 226.翻转二叉树

题目链接LC 226.翻转二叉树
思路:翻转改的是地址而不是值。可以深度遍历或者层次遍历若左右子树不全为空,就将左右子树翻转。
代码

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
 * };
 */
class Solution {
public:
    //深度遍历-先序遍历-递归
    //1 确定传入参数和返回参数类型
    TreeNode* invertTree(TreeNode* root) {
        //2 确定返回条件(终止条件)
        if(root == nullptr)return root;
        //3 单层递归逻辑
        //先反转,再到左右子树(先序遍历)
        swap(root->right, root->left);
        invertTree(root->right);
        invertTree(root->left);
        return(root);
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值