《剑指offer》-替换空格

替换空格

题目:请实现一个函数,把字符串中的每个空格替换成“%20”,例如,输入“We are happy”,则输出“We%20are%20happy”

首先我们确定是,我们不使用额外的空间来解决这个问题。如果使用额外的空间,那么我们对原数组进行遍历,然后一个个插入就行了,这个时候空间复杂度和时间复杂度都为 O(n)

不使用额外空间的做法

第一种方法:从前往后寻找空格

最直观的做法是,从头到尾遍历,每次遇到空格的时候,就把一个空格字符换成对应的 3个字符 ,我们要把空格后面的每个字符都往后移2个字节。假设字符串的长度为 n,对每个空格字符,需要移动后面的 O(n)个字符,因此对于含有O(n)个空格字符的字符串而言,总的时间效率是O(nn)
时间复杂度:O(n
n)
空间复杂度:O(1)

public static String replaceBlank(String str){
    StringBuffer sb = new StringBuffer(str);  // 创建一个StringBuffer,这样每次改变string的时候,不需要使用新的空间
    int length = sb.length(); // 记录sb的长度
    int count = 0; // 统计str中,空格的数量,这部分可以封装一下
    for(int i = 0;i < str.length();i++){
        if (str.charAt(i) == ' '){
            count++;
        }
    }
    sb.setLength(length + 2 * count);  // 根据原字符串中,空格的数量,设置新的长度
    length = sb.length();
    for (int i = 0;i < length;i++){   // 进行遍历
        if (sb.charAt(i) == ' '){      // 如果是空格的话
            for (int j = length-1;j > i+1;j--){  // 从后向前复制字符
                sb.setCharAt(j, sb.charAt(j-2));
            }
            sb.setCharAt(i, '%');     // 从空格的位置开始,设置 %20
            sb.setCharAt(i+1, '2');
            sb.setCharAt(i+2, '0');
        }
    }
    return sb.toString();  // 最后返回的时候,返回成字符串
}

测试用例:

  1. 输入的字符串中包含空格
    1. 空格在最前面
    2. 空格在最后面
    3. 空格在中间
    4. 多个空格
  2. 没有空格
  3. 特殊输入测试
    1. 字符串为空
    2. 字符串只有1个空格字符,没有字母
    3. 字符串只有多个空格字符
第二种做法:从后向前寻找空格,

上面是从前向后寻找空格,找到空格之后,将空格之后的所有字符都往后移动3个位置。但是这就造成了一个问题,后面的字符往往需要移动多次,这就造成了时间复杂度很高。
这里用从后向前寻找,创建两个游标,一个指向原数组末尾,一个指向新数组末尾。对原数组进行遍历,如果是字母,直接在新数组末尾复制,游标向前移动1个位置;如果是空格,则在新数组末尾设置 %20,游标向前移动3个位置。
时间复杂度:第一个游标只对原数组进行了一次遍历,为O(n),第二个游标每次遍历都是O(1)
空间复杂度:在原数组上新增了空间,应该为O(1)

int j = length-1 ;   // 指向新数组末尾
int i = str.length() -1;  // 指向原数组末尾
while (i >= 0 && j > i) {   // 前者判断是否遍历完,后者判断前面是否还有空格
    if (sb.charAt(i) == ' ') {  // 是空格,则设置 %20
        sb.setCharAt(j--, '0');
        sb.setCharAt(j--, '2');
        sb.setCharAt(j--, '%');
    }else if (sb.charAt(i) != ' ') {  // 不是空格,则复制
        sb.setCharAt(j--, sb.charAt(i));
    }
    i--;   // 游标向前
}

测试用例:
同上

相关题目

有两个排序数组,A1和A2,内存在A1的末尾有足够多的空余空间容纳A2,请实现1个函数,把A2中的所有数字都插入A1中,并且数字是排序的。还是从后向前比较比较快

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值