剑指Offer 05.替换空格、151.翻转字符串里的单词

52 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第4天,点击查看活动详情

剑指Offer 05.替换空格

分析题目

题目要求将字符串s中的每个空格替换为"%20"。看到题目我们第一时间会想到开辟一个新的数组,遍历字符串s,如果遇到空格就填入%20。

但是我们可以使用复杂度更低的方法,不需要使用额外的空间,将题目解决。前面的题目我们使用过很多次双指针法,不得不说双指针法真的是很精妙,可以适用于很多题目,这道题也同样可以。

解题

我们可以将字符串转为数组。计算空格的数量,由此得出需要开辟数组空间的大小,通过在原数组中开辟更多的空间。来做到不使用额外的辅助空间。

接下来从后向前替换空格,定义两个指针左指针指向旧数组长度的末尾,右指针指向新数组长度的末尾。通过移动左右指针实现替换。

具体代码如下:

var replaceSpace = function(s) {
  const strArr = Array.from(s);
  let count = 0;
  for(let i = 0; i < strArr.length; i++) {
    if (strArr[i] === ' ') {
      count++;
    }
  }
  let left = strArr.length - 1;
  let right = strArr.length + count * 2 - 1;
  while(left >= 0) {
    if (strArr[left] === ' ') {
      strArr[right--] = '0';
      strArr[right--] = '2';
      strArr[right--] = '%';
      left--;
    } else {
      strArr[right--] = strArr[left--];
    }
  }
  return strArr.join('');
};

由代码可以看出,如果左指针遇到空格,那么幼稚症向左移动三个位置并且赋值%20。

通过从右向左的填充,可以避免从左到右填充时需要移动后面的元素的麻烦。

151.翻转字符串里的单词

分析题目

题目要求反转字符串中单词的顺序,并且字符串中可能会出现前道空格,尾随空格或者是多个空格,需要进行整理。本题可以通过先分隔单词,然后再把单词倒序相加。但是如果这样做这道题就没有了意义。我们要不使用辅助空间来解决这道题。

解题

这道题可以先将整个字符串都反转过来,再反转单词。所以整体的思路是

  1. 移除多余的空格
  2. 将整个字符串反转
  3. 将每个单词反转

移除多余的空格可以参考27.移除元素这道题,可以参考我之前写的题解,通过双指针的方式移除某一个特定的元素。反转也在之前的题目中遇到过,这道题本身并不难,只不过因为结合了很多知识,所以比较复杂。

代码在JS中给出。