剑指offer面试题 - 05 替换空格

替换空格

题目描述

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

分析

显然,最直观的解法就是从头到尾遍历输入字符串,遇到空格则进行替换,但是由于替换后的"%20"是3个字符,而原本的空格只有1个字符,替换过程中必然会出现需要将空格后的字符向后移动的情况。例如输入“We are happy.”进行第一个空格替换时,"are happy."需要向后移动两个位置,而进行第二个空格的替换时,"happy."又需要移动一次,也就是说每个空格的替换都会导致其后面的字符发生一次移动。对于长度为n的字符串,包含O(n)个空格,每个空格的替换导致其后面O(n)个字符的移动,其时间复杂度为O(n^2)。
为了降低时间复杂度,我们可以考虑从后向前进行替换。首先遍历一遍输入字符串记录空格的数量,这样就可以计算得到替换后字符串的长度。然后用两个索引idOld, idNew分别指示原始字符串与输入字符串的元素下标,初始化为字符串各自的最后一个下标。接着从后向前,若原始字符串idOld位置不是空格,则赋值给新字符串对应idNew位置;否则,则从后向前向新字符串赋值’0’, ‘2’, ‘%’。这一过程要注意每次对新字符串赋值后索引idNew都要递减1,遍历原始字符串idOld位置的元素后也要对idOld递减1.
C++代码如下。目前采用的是vector来记录输入输出,实际采用char str[]或string类型是一样的,注意边界即可。算法上主要注意要考虑到正向遍历的额外开销,实现上则要注意索引值的递减。

vector<char> replaceBlank(vector<char> str) {
  int len = str.size(), numBlank = 0;
  for (auto c : str) {
    if (c == ' ') ++numBlank;
  }
  int newLen = len + 2 * numBlank;
  vector<char> ans(len);
  int idOld = len - 1, idNew = newLen - 1;
  while (idOld >= 0 && idNew >= 0) {
    if (str[idOld] == ' ') {
      ans[idNew--] = '0';
      ans[idNew--] = '2';
      ans[idNew--] = '%';
    } else {
      ans[idNew--] = str[idOld];
    }
    --idOld;
  }
  return ans;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值