代码随想录算法训练营第8天 | 344&541.反转字符串 I&II、剑指05.替换空格、151.翻转字符串里的单词、剑指58-II.左旋转字符串

day8

344.反转字符串

可以left<right 更直接

class Solution {
public:
    void reverseString(vector<char>& s) {
        int len = s.size();
        char tmp;
        for (int i = 0; i < len / 2; i++) {
            tmp = s[i];
            s[i] = s[len - 1 - i];
            s[len - 1 - i] = tmp;
        }
        return ;
    }
};

541. 反转字符串II

c++参数传递,没加&是拷贝过来一份,所以要返回string作为结果。

class Solution {
public:
    void reverse(string& s, int cur, int k) {
        for (int i = cur, j = cur + k - 1; i < j; i++, j--)
            swap(s[i], s[j]);
    }

    string reverseStr(string s, int k) {
        int len = s.size();
        int cur = 0;
        for (cur = 0; cur + 2*k <= len; cur += 2*k) {
            reverse(s, cur, k);
        }
        if (cur + k > len) reverse(s, cur, len - cur);
        else reverse(s, cur, k);
        return s;
    }
};

剑指05.替换空格

因为是string,空格替换成 “%20” 要多两个char,第一思路是用另一个string来返回,这样可能时间上比较快?缺点是用了额外的辅助空间。

Karl的思路也很有意思,又是一次双指针的美妙使用,既然string每次加东西,后面的元素都要后移,那直接第一遍遍历算好一共要移多少空间,然后再用双指针从后往前拉回来。

建议:对于线性数据结构(非链表),填充或者删除,后序处理会高效的多。——Karl

class Solution {
public:
    string replaceSpace(string s) {
        int num = 0;
        for (char c: s) 
            if (c == ' ') num++;
        int i = s.size() - 1;
        s.resize(s.size() + num*2);
        int j = s.size() - 1;
        // cout << i <<" "<< j;
        for (; i >= 0; i--,j--) {
            if (s[i] == ' ') {
                s[j] = '0'; s[j-1] = '2'; s[j-2] = '%';
                j -= 2;
            }
            else  s[j] = s[i];
        }
        return s;
    }
};

用栈写的屎山:

class Solution {
public:
    string reverseWords(string s) {
        stack<string> st;
        int len = s.size();
        int i = 0;
        while (i < len) {
            while (i < len && s[i] == ' ') i++;

            string tmp;
            while (i < len && s[i] != ' ') {
                tmp.push_back(s[i]);
                i++;
            }
            if (tmp.size() > 0) st.push(tmp);
        }
        string res;
        res = res + st.top();
        st.pop();
        while (!st.empty()) {
            res.append(" ");
            res.append(st.top());
            st.pop();
        }
        return res;
    }
};

151.翻转字符串里的单词

这题好麻烦,理不清就显得好难。

确实很综合。

class Solution {
public:
    string reverseWords(string s) {
        reverse(s.begin(),s.end());
        //删除多余空格
        int slow = 0, fast = 0;
        // 越过开头的空格
        while (s[fast] == ' ')  fast++;
        //找中间的空格
        while (fast < s.size()) {
            if (s[fast] != ' ') {
                s[slow++] = s[fast++];
            }
            else {
                s[slow++] = ' ';
                while (fast < s.size() && s[fast] == ' ') fast++;
            }
        }
        // 剔除最后的空格
        int last = slow - 1;
        while (s[last] == ' ') last--;
        s.resize(last + 1);

        // 对逐个单词的反转
        for (slow =0, fast =0; fast <= s.size(); fast++){
            if (fast >= s.size() || s[fast] == ' '){
                reverse(s.begin() + slow, s.begin() + fast);
                slow = fast + 1;
            }
        }
        return s;
    }
};

另外对 reverse()函数(#include <algorithm>)也熟悉了一下,有两种用法:

反转数组:reverse(a, a+n); //n为数组中的元素个数

反转字符串 :reverse(str.begin(), str.end());

反转向量:reverse(vec.begin(), vec.end());

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

首先,基本的string操作得会用。

string reverseLeftWords(string s, int n) {
    string tmp1 = s.substr(0, n), tmp2 = s.substr(n);
    return tmp2.append(tmp1);
}

确实妙啊!局部反转在整体反转,和前面的题目融会贯通了。

class Solution {
public:
    string reverseLeftWords(string s, int n) {
        reverse(s.begin(), s.begin() + n);
        reverse(s.begin() + n, s.end());
        reverse(s.begin(), s.end());
        return s;
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值