代码随想录训练营第八天| ● 344.反转字符串● 541. 反转字符串II● 剑指Offer 05.替换空格● 151.翻转字符串里的单词● 剑指Offer58-II.左旋转字符串

文章介绍了如何使用双指针法反转字符串,以及在不同场景下处理字符串,如替换空格、翻转单词和左旋转字符串,强调了编程技巧和逻辑理解的重要性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

344.反转字符串

void reverseString(vector<char>& s) {
        int length = s.size();
        int left = 0;
        int right = length-1;
        while (left < right) {
            char temp = s[left];
            s[left] = s[right];
            s[right] = temp;
            left++;
            right--;
        }
    }

本题是很简单的双指针做法,很简单没什么可说的。唯一要注意的是不要直接调用库函数来解决,这样就丧失了理解原理的作用了。

void reverseString(vector<char>& s) {
        for (int i = 0, j = s.size() - 1; i < s.size()/2; i++, j--) {
            swap(s[i],s[j]);
        }
    }

这是示例代码,使用了swap函数和循环来做的,更加简洁

541. 反转字符串II

void reverse(string& s, int start, int end) {
        for (int i = start,j = end; i < j; i++, j--) {
            swap(s[i], s[j]);
        }
    }
    string reverseStr(string s, int k) {
        int length = s.size();
        for (int i = 0; i < length; i += 2*k) {
            if (i+k <= length) {
                reverse(s, i, i+k-1);
            }
            else {
                reverse(s, i, length-1);
            }
        }
        return s;
    }

模拟题,使用循环i+=2*k来进行计数每2k个数,若后面还有k个数字或更多,则翻转k个字母,否则翻转至结尾的字母。这道题的启示是当要一段一段去处理数据的时候,循环中的索引可以不只加一,而是可以加一整段。

剑指Offer 05.替换空格

题目链接/文章讲解: 代码随想录
string pathEncryption(string path) {
        string result = "";
        for (int i = 0; i < path.size(); i++) {
            if (path[i] != '.')
                result += path[i];
            else result += ' '; 
        }
        return result;
    }

 这道题好像很轻松,直接将.替换即可。

原来是力扣貌似把剑指offer的题删掉了,原来第题目是这样的:

请实现一个函数,把字符串 s 中的每个空格替换成"%20"。

示例 1: 输入:s = "We are happy."
输出:"We%20are%20happy."

string replaceSpace(string s) {
        int count = 0; // 统计空格的个数
        int sOldSize = s.size();
        for (int i = 0; i < s.size(); i++) {
            if (s[i] == ' ') {
                count++;
            }
        }
        // 扩充字符串s的大小,也就是每个空格替换成"%20"之后的大小
        s.resize(s.size() + count * 2);
        int sNewSize = s.size();
        // 从后先前将空格替换为"%20"
        for (int i = sNewSize - 1, j = sOldSize - 1; j < i; i--, j--) {
            if (s[j] != ' ') {
                s[i] = s[j];
            } else {
                s[i] = '0';
                s[i - 1] = '2';
                s[i - 2] = '%';
                i -= 2;
            }
        }
        return s;
    }

这道题不再开一个字符串来存储答案的做法是这样的,首先先算出字符串中的空格数量,然后将原有的字符串扩容,再通过双指针的方法,一个指针指向原字符串最后一个字母,一个指针指向现在字符串的结尾,从后向前来填充字符串和%20即可。

其实很多数组填充类的问题,都可以先预先给数组扩容带填充后的大小,然后在从后向前进行操作。

这么做有两个好处:

  1. 不用申请新数组。
  2. 从后向前填充元素,避免了从前向后填充元素时,每次添加元素都要将添加元素之后的所有元素向后移动的问题。

 151.翻转字符串里的单词

题目链接/文章讲解/视频讲解: 代码随想录
void removeExtraSpace(string& s) {      //使用双指针做法
        int slow = 0, fast = 0;
        //先移除前面的空格
        for (int i = 0; i < s.size(); i++) {
            if (s[i] == ' ')
                fast++;
            else break;
        }
        //再去除中间多余的空格
        for (; fast < s.size(); fast++) {
            if (fast-1 > 0 && s[fast] == ' ' && s[fast] == s[fast-1])
                continue;       //如果有两个重复空格则跳过
            else {
                s[slow++] = s[fast];
            }
        }
        //再去除尾部的空格
        if (s[slow-1] == ' ')
            s.resize(slow-1);
        else s.resize(slow);
        
    }
    string reverseWords(string s) {
        removeExtraSpace(s);
        reverse(s.begin(), s.end());
        int left = 0;
        for (int i = 0; i < s.size(); i++) {
            if (s[i] == ' ') {
                reverse(s.begin()+left, s.begin()+i);
                left = i+1;
            }
            else if (i == s.size()-1)
                reverse(s.begin()+left, s.end());
        } 
        return s;
    }

 这道题应该先去除头部、中间重复的和尾部的空格再进行翻转单词操作。在去除空格函数中,采用的是双指针的方法,如果快指针找到要删除的空格则跳过,否则就让满指针的位置复制上快指针的元素,最后在调整字符串大小即可完成去空格。在翻转单词部分,也很简单,只需要全部翻转字符串,然后再在遇到空格的地方,翻转相应的单词即可完成单词翻转。

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

string dynamicPassword(string password, int target) {
        reverse(password.begin(), password.end());
        reverse(password.begin(), password.end()-target);
        reverse(password.end()-target, password.end());
        return password;
    }

这道题只需先全部翻转,然后再按照target的位置,翻转后就是从后向前第target的位置在相应做翻转操作即可

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值