[日记]LeetCode算法·七——字符串①

1 替代空格

LeetCode:替代空格

利用扩充的字符串和双指针,利用前后长度的区别来移动两指针直到相遇为止。

class Solution {
public:
    string replaceSpace(string s) {
        //计算空格数
        int spaceCount=0;
        for(int i=0;i<s.size();i++)
        {
            if(s[i]==' ')
                ++spaceCount;
        }
        //记录前后长度,并扩充
        int old_size=s.size();
        s.resize(s.size()+2*spaceCount);
        int new_size=s.size();
        //双指针
        int i=old_size-1;
        int j=new_size-1;
        while(i<j)
        {
            if(s[i]!=' ')
            {
                s[j]=s[i];
            }
            else
            {
                s[j--]='0';
                s[j--]='2';
                s[j]='%';
            }
            --i;
            --j;
        }
        return s;
    }
};

2 反转字符串中的单词

LeetCode:反转字符串中的单词

本题考察在不额外利用空间的情况下对字符串进行反转,并且考虑前导空格、尾随空格与多余空格的情况。
事实上反转单词可以分为三个步骤进行:去除多余空格、反转整个字符串、反转每个单词。

class Solution {
public:
    //去除多余空格
    void removeExtraSpace(string& s)
    {
        //双指针
        //快慢指针,快指针遍历原字符串,慢指针更新新字符串
        int fast=0;
        int slow=0;
        //前导空格
        while(s[fast]==' ')
            ++fast;
        //中间更新新字符串
        //每个单词后面都会有一个空格(末尾除外)
        for(;fast<s.size();fast++)
        {
            if(fast>0 && s[fast]==' ' && s[fast-1]==' ')
            {
                continue;
            }
            else
            {
                s[slow++]=s[fast];
            }
        }
        if(s[slow-1]==' ')
            s.resize(slow-1);
        else
            s.resize(slow);
    }
    //部分翻转
    void reversePart(string& s,int start,int end)
    {
        while(start<end)
        {
            char tmp=s[start];
            s[start]=s[end];
            s[end]=tmp;
            ++start;
            --end;
        }
    }
    string reverseWords(string s) {
        //去除空格
        removeExtraSpace(s);
        //句子翻转
        reversePart(s,0,s.size()-1);
        //双指针定位单词
        int left=0;
        int right=0;
        while(right<s.size())
        {
            if(right==s.size()-1 || s[right+1]==' ')
            {
                reversePart(s,left,right);
                right+=2;
                left=right;
            }
            else
            {
                ++right;
            }
        }
        return s;
    }
};

3 有效的字母异位词

LeetCode:有效的字母异位词

经典的一道哈希计数题,字母异位词代表着两个单词的各个字母计数理应一致,使用哈希再简单不过。

class Solution {
public:
    bool isAnagram(string s, string t) {
        if(s.size()!=t.size())return false;
        //记录各个字母的个数
        int record[26]={0};
        int size=s.size();
        for(int i=0;i<size;++i)
        {
            ++record[s[i]-'a'];
            --record[t[i]-'a'];
        }
        for(int i=0;i<26;++i)
        {
            if(record[i]!=0)
                return false;
        }
        return true;
    }
};

4 反转字符串II

LeetCode:反转字符串II

十分简单的一道题,过。

class Solution {
public:
    void reversePart(string& s,int start,int end)
    {
        while(start<end)
        {
            char tmp=s[start];
            s[start]=s[end];
            s[end]=tmp;

            ++start;
            --end;
        }
    }
    string reverseStr(string s, int k) {
        int size=s.size();
        int k_count=size/(2*k);
        //前k个2k进行翻转
        for(int i=0;i<k_count;i++)
        {
            reversePart(s,2*k*i,2*k*i+k-1);
        }
        //最后不足2k的进行处理
        int length=min(k,size%(2*k));
        reversePart(s,2*k*k_count,2*k*k_count+length-1);
        return s;
    }
};

5 左旋转字符串

LeetCode:左旋转字符串

如果利用额外空间,这将是一道十分简单的题目。但在不能使用额外空间的情况下,那么,左旋转字符串将等效于三次翻转:左Part翻转+右Part翻转+整体翻转。

class Solution {
public:
    void reversePart(string& s,int start,int end)
    {
        while(start<end)
        {
            char tmp=s[start];
            s[start]=s[end];
            s[end]=tmp;

            ++start;
            --end;
        }
    }
    string reverseLeftWords(string s, int n) {
        //想象为三次翻转
        //两次局部反转+一次整体反转
        reversePart(s,0,n-1);
        reversePart(s,n,s.size()-1);
        reversePart(s,0,s.size()-1);
        return s;
    }
};

6 总结

今天摆了,没什么好说的。因为下午捣鼓ChatGPT的缘故,没有怎么花时间进行刷题和学习。另外早上一节课,下午当助教上一节课,晚上又一节课,只能给自己找找借口偷懒了。
明天开始对字符串的学习将集中于KMP这个大名鼎鼎的算法,恐怕博客也将不只是单纯的LeetCode展示了。
另外开始学习极简主义的MarkDown美学,除了加粗和标题,别的已经懒得用了。
——2023.2.21

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值