替换空格

271 阅读3分钟

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

剑指 Offer 05. 替换空格

leetcode:leetcode-cn.com/problems/ti…

GitHub:github.com/nateshao/le…

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

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

限制: 0 <= s 的长度 <= 10000

方法一:遍历添加

遇到空格就在后面添加“ %20

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

算法流程:

  • 初始化一个 list (Python) / StringBuilder (Java) ,记为 res ;

  • 遍历列表 s 中的每个字符 c :

    • 当 c 为空格时:向 res 后添加字符串 "%20" ;
    • 当 c 不为空格时:向 res 后添加字符 c ;
    • 将列表 res 转化为字符串并返回。

复杂度分析:

  • 时间复杂度 O(N) : 遍历使用O(N) ,每轮添加(修改)字符操作使用 O(1) ;
  • 空间复杂度 O(N): 新建的 StringBuilder 都使用了线性大小的额外空间。
 package com.nateshao.sword_offer.topic_04_replaceSpace;
 
 /**
  * @date Created by 邵桐杰 on 2021/11/15 23:12
  * @个人网站 www.nateshao.cn
  * @博客 https://nateshao.gitee.io
  * @GitHub https://github.com/nateshao
  * @Gitee https://gitee.com/nateshao
  * Description: 替换空格
  */
 public class Solution {
     public static void main(String[] args) {
         String str = "We Are Happy";
         String s = replaceSpace(str);
         System.out.println(s);
     }
 
     public static 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();
 
 //        if (s == null)
 //            return null;
 //        StringBuilder sb = new StringBuilder();
 //        for (int i = 0; i < s.length(); i++) {
 //            if (String.valueOf(s.charAt(i)).equals(" ")) {
 //                sb.append("%20");
 //            } else {
 //                sb.append(s.charAt(i));
 //            }
 //        }
 //        return String.valueOf(sb);
     }
 }
 

Go实现

// 遍历添加
func replaceSpace(s string) string {
    b := []byte(s)
    result := make([]byte, 0)
    for i := 0; i < len(b); i++ {
        if b[i] == ' ' {
            result = append(result, []byte("%20")...)
        } else {
            result = append(result, b[i])
        }
    }
    return string(result)
}

方法二:字符数组

由于每次替换从 1 个字符变成 3 个字符,使用字符数组可方便地进行替换。建立字符数组地长度为 s 的长度的 3 倍,这样可保证字符数组可以容纳所有替换后的字符。

  • 获得 s 的长度 length

  • 创建字符数组 array,其长度为 length * 3

  • 初始化 size 为 0,size 表示替换后的字符串的长度

  • 从左到右遍历字符串 s

    • 获得 s 的当前字符 c
    • 如果字符 c 是空格,则令 array[size] = '%',array[size + 1] = '2',array[size + 2] = '0',并将 size 的值加 3
    • 如果字符 c 不是空格,则令 array[size] = c,并将 size 的值加 1
  • 遍历结束之后,size 的值等于替换后的字符串的长度,从 array 的前 size 个字符创建新字符串,并返回新字符串

复杂性分析

  • 时间复杂度:O(n)。遍历字符串 s 一遍。
  • 空间复杂度:O(n)。额外创建字符数组,长度为 s 的长度的 3 倍。
     /**
      * 方法二:字符数组
      * @param s
      * @return
      */
     public String replaceSpace2(String s) {
         int length = s.length();
         char[] array = new char[length * 3];
         int size = 0;
         for (int i = 0; i < length; i++) {
             char c = s.charAt(i);
             if (c == ' ') {
                 array[size++] = '%';
                 array[size++] = '2';
                 array[size++] = '0';
             } else {
                 array[size++] = c;
             }
         }
         String newStr = new String(array, 0, size);
         return newStr;
     }

还有一种解法,这个看看就好哈哈

 public String replaceSpace(String s) {
     return s.replace(" ","%20");
 }

用Go实现

// 原地修改
func replaceSpace(s string) string {
    b := []byte(s)
    length := len(b)
    spaceCount := 0
    // 计算空格数量
    for _, v := range b {
        if v == ' ' {
            spaceCount++
        }
    }
    // 扩展原有切片
    resizeCount := spaceCount * 2
    tmp := make([]byte, resizeCount)
    b = append(b, tmp...)
    i := length - 1
    j := len(b) - 1
    for i >= 0 {
        if b[i] != ' ' {
            b[j] = b[i]
            i--
            j--
        } else {
            b[j] = '0'
            b[j-1] = '2'
            b[j-2] = '%'
            i--
            j = j - 3
        }
    }
    return string(b)
}

思路:栈

采用栈的方式倒序写入遍历,虽然效率不是很高,但是也算提供另外一种解题思路吧。

倒序遍历字符串数组, 遇到' ',将'0','2','%'压入栈,若为正常字符直接入栈,随后依次出栈+拼串,完成操作。


class Solution {
    public String replaceSpace(String s) {
        char[] chars = s.toCharArray();
        Stack<Character> stack = new Stack<>();
        for (int i = s.length() - 1; i >= 0; i--) {
            if (chars[i] == ' ') {
                stack.push('0');
                stack.push('2');
                stack.push('%');
            } else {
                stack.push(chars[i]);
            }
        }
        String s1 = "";
        while (!stack.isEmpty()) {
            Character pop = stack.pop();
            s1 += pop;
        }
        return s1;
    }
}

参考链接:

  1. leetcode-cn.com/problems/ti…
  2. leetcode-cn.com/problems/ti…