【剑指Offer】个人学习笔记_ 05_ 替换空格

刷题日期:21:2208 星期四2021年3月11日

个人刷题记录,代码收集,来源皆为leetcode

主要答题语言为C++

题目:

剑指 Offer 05. 替换空格

难度简单81

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

示例 1:

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

限制:

0 <= s 的长度 <= 10000

初始解答:

字符串的处理基本功还很差,参考了书本。

class Solution {
public:
    string replaceSpace(string s) {
        // if(s == '\0' && length <= 0)
        //     return false;
        int originalLength = 0;
        int numberOfBlank = 0;
        int i = 0;
        while(s[i] != '\0')
        {
            ++ originalLength;

            if(s[i] == ' ')
                ++ numberOfBlank;

            ++ i;
        }
        int newLength = originalLength + numberOfBlank * 2;
        // if(newLength > originalLength)
        //     return true;
        int indexOfOriginal = originalLength;
        int indexOfNew = newLength;
        while(indexOfOriginal >= 0 && indexOfNew > indexOfOriginal)
        {
            if(s[indexOfOriginal] == ' ')
            {
                s[indexOfNew --] = '0';
                s[indexOfNew --] = '2';
                s[indexOfNew --] = '%';
            }
            else
            {
                s[indexOfNew --] = s[indexOfOriginal];
            }

            -- indexOfOriginal;
        }
        return s;
    }
};

基础不扎实,老是报错:

在这里插入图片描述

参考了算法一后的结果,有些参数没必要用两遍,中间有一句s += string(numberOfBlank * 2,' ');没懂为什么添加。

class Solution {
public:
    string replaceSpace(string s) {
        if(s.length()==0)
            return s;
        int originalLength = s.size() - 1;
        int numberOfBlank = 0;
        int i = 0;
        while(s[i] != '\0')
        {

            if(s[i] == ' ')
                ++ numberOfBlank;

            ++ i;
        }
        int newLength = originalLength + numberOfBlank * 2;
        s += string(numberOfBlank * 2,' '); //没懂为啥
        // int indexOfOriginal = s.size() - 1;
        // int indexOfNew = newLength;
        while(originalLength >= 0 && newLength > originalLength)
        {
            if(s[originalLength] == ' ')
            {
                s[newLength --] = '0';
                s[newLength --] = '2';
                s[newLength --] = '%';
            }
            else
            {
                s[newLength --] = s[originalLength];
            }

            -- originalLength;
        }
        return s;
    }
};

执行结果:

通过

显示详情

执行用时:0 ms, 在所有 C++ 提交中击败了100.00%的用户

内存消耗:6.2 MB, 在所有 C++ 提交中击败了44.96%的用户

学习他人:

Yuz7

2020-04-12 不用额外字符串

方法一:

思路相同,代码更简洁

class Solution {
public:
    string replaceSpace(string s) {
        if(s.length()==0) return s;
        int originallen = s.size() - 1;
        int numblank = 0;
        for(auto c:s){
            if(c == ' ') ++numblank;
        }
        int newlen = originallen + numblank * 2;
        s += string(numblank * 2,' ');
        while(originallen>=0 && newlen > originallen){
            if(s[originallen] == ' '){
                s[newlen--] = '0';
                s[newlen--] = '2';
                s[newlen--] = '%';
            }
            else{
                s[newlen--] = s[originallen];
            }
            originallen--;
        }
        return s;
    }
};

比较相似,找出了自己差不多的版本,很复杂。

方法二:


The queen of PrideL1

2020-02-13 这题多欢乐?

class Solution {
public:
    string replaceSpace(string s) {
        string ans;
        for(int i = 0; i<s.size(); i++) {
            if(s[i] == ' ') {
                ans +="%20";
            }
            else    ans+=s[i];
        }
        return ans;
    }
};

遍历字符串,遇到字符加字符,遇到空格加%20,最后返回新建的字符串,算取巧不过确实优秀。

只有不断加的过程,更加简单。

方法三:

Jolly LovelacedBGL1

2021-01-28 使用内置函数:Python3, Java, Kotlin

class Solution:
    def replaceSpace(self, s: str) -> str:
        return s.replace(" ","%20")

判断空矩阵以及是否满足输入要求的部分是值得学习的,如果没有该判断的话,也会卡再前面我尝试过的错误那里。

其他区别

jyd
链接:https://leetcode-cn.com/problems/ti-huan-kong-ge-lcof/solution/mian-shi-ti-05-ti-huan-kong-ge-ji-jian-qing-xi-tu-/
来源:力扣(LeetCode)

在 Python 和 Java 等语言中,字符串都被设计成「不可变」的类型,即无法直接修改字符串的某一位字符,需要新建一个字符串实现。

class Solution {
    public String replaceSpace(String s) {
        StringBuilder res = new StringBuilder();
        for(Character c : s.toCharArray())
        {
            if(c == ' ') res.append("%20");
            else res.append(c);
        }
        return res.toString();
    }
}

在 C++ 语言中, string 被设计成「可变」的类型(参考资料),因此可以在不新建字符串的情况下实现原地修改。

class Solution {
public:
    string replaceSpace(string s) {
        int count = 0, len = s.size();
        // 统计空格数量
        for (char c : s) {
            if (c == ' ') count++;
        }
        // 修改 s 长度
        s.resize(len + 2 * count);
        // 倒序遍历修改
        for(int i = len - 1, j = s.size() - 1; i < j; i--, j--) {
            if (s[i] != ' ')
                s[j] = s[i];
            else {
                s[j - 2] = '%';
                s[j - 1] = '2';
                s[j] = '0';
                j -= 2;
            }
        }
        return s;
    }
};

教材示例代码

书里的版本先设置了一个bool型参数found,我也参考了这个意见。不过对比发现leetcode上的版本和书里的问题初始设置的代码并不相同。

void ReplaceBlank(char str[], int length)
{
    if(str == nullptr && length <= 0)
        return;

    /*originalLength Ϊ�ַ���str��ʵ�ʳ���*/
    int originalLength = 0;
    int numberOfBlank = 0;
    int i = 0;
    while(str[i] != '\0')
    {
        ++ originalLength;

        if(str[i] == ' ')
            ++ numberOfBlank;

        ++ i;
    }

    /*newLength Ϊ�ѿո��滻��'%20'֮��ij���*/
    int newLength = originalLength + numberOfBlank * 2;
    if(newLength > length)
        return;

    int indexOfOriginal = originalLength;
    int indexOfNew = newLength;
    while(indexOfOriginal >= 0 && indexOfNew > indexOfOriginal)
    {
        if(str[indexOfOriginal] == ' ')
        {
            str[indexOfNew --] = '0';
            str[indexOfNew --] = '2';
            str[indexOfNew --] = '%';
        }
        else
        {
            str[indexOfNew --] = str[indexOfOriginal];
        }

        -- indexOfOriginal;
    }
}

看完之后再看这段代码,妥妥的裹脚布。

总结

以上就是本题的内容和学习过程了,虽然有很多简短的方法,但是书中进行替换的思路是值得学习的。

欢迎讨论,共同进步。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值