剑指Offer:面试题05——替换空格(java,c)

替换空格

问题描述:

  • 请实现一个函数,将一个字符串中的所有空格替换成“%20”
  • 这道题其实本身没有说清楚是针对于字符串还是针对于字符串数组,所以这里分类进行讨论

算法思路一:

  • 如果是字符串,对于java语言来说,这道题有一个非常容易的解法,那就是直接使用String类的replaceAll方法,但是实际上面试算法都是考查能力的,不会让你直接用接口写
  • 但是我们可以自己去实现replaceAll中的源码来回答这个问题,用StringBuild,只需要遍历该字符串,根据题目要求构建返回一个新的字符串即可!
  • 这个算法的时间复杂度也是O(n)的,所以也是比较好的!
public static String replaceStr(String str){
        StringBuilder result = new StringBuilder("");
        for(int i = 0; i < str.length(); i++){
            if(str.charAt(i) == ' '){
                result.append("%20");
            }else {
                result.append(str.charAt(i));
            }
        }
         return new String(result);
    }

算法思路二:(针对于c,c++)

  • 但是如果是字符数组,就显然没有这么容易了,当然将字符数组先转化为字符串进行操作,然后再转回来也不失为一种不错的解法,这里还给出另外一种解法

  • 如果从头开始遍历,每次遇见空格就替换“%20”,这样就会导致每次要多增加两个容量的位置,所以每次替换的时候都需要将后面的字符全部移两个位置,这样的算法复杂度太高了,并且一般情况下不会设计这样的算法。

  • 为了不进行元素的移动,我们可以尝试从尾部开始遍历,如果从尾部开始遍历,如果遇见空格替换就不需要进行元素的移动了

  • 但是实现这种算法的前提是我们必须控制好字符数组的容量,知道尾部在哪里。
    所以我们必须提前遍历字符数组,找出所有空格的数量,然后就可以求出我们转换后结果的字符数组的容量,再从这个尾部开始遍历即可

  • 为什么说这种算法只针对于c语言和c++呢?因为c语言和c++的字符数组尾部结尾都是以‘/0’结尾,并且字符数组的最大容量可以和实际存储容量不同。但是实际上java中一般不会有字符数组的结尾,一般都是动态定义初始化的!

public static void ReplaceBlank(char[] target, int maxLength)
    {
        if (target == null || maxLength <= 0)
        {
            return;
        }

        // originalLength 为字符串target的实际长度
        int originalLength = 0;
        int blankCount = 0;
        int i = 0;

        while (target[i] != '\0')
        {
            originalLength++;
            // 计算空格数量
            if (target[i] == ' ')
            {
                blankCount++;
            }
            i++;
        }

        // newLength 为把空格替换成'%20'之后的长度
        int newLength = originalLength + 2 * blankCount;
        if (newLength > maxLength)
        {
            return;
        }

        // 设置两个指针,一个指向原始字符串的末尾,另一个指向替换之后的字符串的末尾
        int indexOfOriginal = originalLength;
        int indexOfNew = newLength;

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

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值