【攻克剑指offer】第2天《替换空格》

本文介绍了Java中替换字符串空格的三种方法:使用String的replaceAll和replace方法,以及使用StringBuilder和字符数组。详细解析了每种方法的实现原理和性能分析,强调了StringBuilder在处理字符串操作时的效率优势,并给出了优化空间占用的解法。同时,探讨了String、StringBuilder和StringBuffer的区别。
摘要由CSDN通过智能技术生成


题目描述: 💦
在这里插入图片描述
👉题目链接👈

🏠解法一、利用字符串中现有的方法

简单做一下java的String函数笔记:
public String replaceAll(String regex,String replacement)
用给定的替换替换与给定的regular expression匹配的此字符串的每个子字符串
参数
regex - 要匹配此字符串的正则表达式
replacement - 要替换每个匹配的字符串

public String replace(CharSequence target,CharSequence replacement)
将与字面目标序列匹配的字符串的每个子字符串替换为指定的字面替换序列
替换从字符串开始到结束,例如,在字符串“aaa”中用“b”替换“aa”将导致“ba”而不是“ab”。
参数
target - 要替换的char值序列
replacement - char值的替换顺序

代码如下 👇

 class Solution {
        public String replaceSpace(String s) {
            return s.replace(" ","%20");
        }
    }
——☀️★☼☻🥛🍽️☻☼★☕*.——

🏠解法二、使用StringBuilder

首先得先明白String、StringBuffer、StringBuilder的区别:

StringBuffer代表一个字符序列可变的字符串,当一个StringBuffer被创建以后,通过StringBuffer提供的append()、insert()、reverse()、setCharAt()、setLength()等方法可以改变这个字符串对象的字符序列。一旦通过StringBuffer生成了最终想要的字符串,就可以调用它的toString()方法将其转换为一个String对象

StringBuilder也代表可变字符串对象。实际上,StringBuilder和StringBuffer基本相似,两个类的构造器和方法也基本相同。不同的是:StringBuffer是线程安全的,而StringBuilder则没有实现线程安全功能,所以性能略高
所以有StringBuilder,我们就可以在一次for循环中直接判断是否为空格然后直接操作字符串。
append():将各种数据类型变量的字符串形式追加到当前序列中

想了解更多更详细的String、StringBuffer与StringBuilder的区别点击此处👉详细解释👈

代码如下👇

class Solution {
public String replaceSpace(String s) {

 StringBuilder sb = new StringBuilder(); //初始化一个 StringBuilder 实例 sb
 
//遍历字符串 s 的每个字符,我这里用的for-each循环既简便又可以避免循环条件和更新语句写错 
//for(数据类型 变量名:集合对象名)  
   for (char c : s.toCharArray()) {   //==for(int i=0;i<s.length();i++)
 
       if (c == ' ') sb.append("%20");  //1.当遍历到非空字符的时候,直接将字符 append 到 sb 中
    
       else sb.append(c);    //2.如果遍历到的是空字符,那么将 %20 append 到 sb 中   
   }
   return sb.toString();  //3.返回 sb.toString
}
}

以上算法实现的复杂度分析:

  • 时间复杂度是: O(n)
  • 空间复杂度是 : O(n)
——☀️★☼☻🥛🍽️☻☼★☕*.——

🏘️解法三、数组

上种解法使用StringBuilde其实它本质上是一个 char 类型的动态数组:
当初始化 StringBuilder 的时候,会初始化一个固定长度的 char 类型的数组
当往 StringBuilder 中 append 数据的时候,其实就是往 char 类型的数组最后追加数据那么,当追加的数据的个数超过了数组的大小的时候,就需要对 char 类型的数据进行扩容了,所以这里的扩容还是有点性能损耗的
,既然都是数组那我们当然可以使用静态数组来解决问题了,从而可以消除数组动态扩容带来的性能损耗。

思路分析: 💫

  1. 我们要定义一个数组,但是不知长度,所以就设为n
  2. 我们知道一个“空格”可以转换为“%20”,但是又不知道数组里有多少个空格,但是知道是1:3的关系,所以我们可以极限处理设为3n
  3. 数组创建成功了,就下来就是判断了,我们使用双指针来判断
  4. 一个指针指向原数组索引为0的位置,另一个指针指向新开辟的静态数组索引为0的位置,然后遍历原数组,
  5. 如果不为空格则直接赋值给静态数组,为空格则将%20依次赋值到静态数组中

代码如下👇

class Solution {
    public String replaceSpace(String s) {
        int n = s.length();
        char[] newArr = new char[3 * n];
        int j = 0;
        for (int i = 0; i < n; i++) {
            char c = s.charAt(i);
            if (c == ' ') {
                newArr[j++] = '%';
                newArr[j++] = '2';
                newArr[j++] = '0';
            } else {
                newArr[j++] = c;
            }
        }
        return new String(newArr, 0, j);
    }
}

但是你会发现如果原数组长度并不大呢,那么新开辟的空间不就浪费的很多吗
在这里插入图片描述
为了不浪费空间,所以我就需要事先知道数组长度
看下面图原数组一共有6个字符但是有2个空格,所以还需要格外的2*2=4个
所以只需找出原数组中有多少个空格就可以了
在这里插入图片描述

完善代码如下 👇

class Solution {
  public String replaceSpace(String s) {
        int n = s.length();
        int cnt = 0;
        for (char c : s.toCharArray()) {   //遍历数组
            if (c == ' ') { 
                cnt++;    //计算出一共有多少个空格
            }
        }
        char[] newArr = new char[n + 2 * cnt];
        int j = 0;
        for (int i = 0; i < n; i++) {
            char c = s.charAt(i);
            if (c == ' ') {
                newArr[j++] = '%';
                newArr[j++] = '2';
                newArr[j++] = '0';
            } else {
                newArr[j++] = c;
            }
        }
        return new String(newArr, 0, j);
    }
}

以上算法实现的复杂度分析:

  • 时间复杂度是: O(n)
  • 空间复杂度是 : O(n)

相关文章:
上一篇:【剑指offer】之《数组中重复的数字》
下一篇:【剑指offer】之《斐波那契数列》

🌈我的感受:

  我突然爱上了数组,太妙了,有遍历的题大多都少不了数组搭配,当然了有直接解法那肯定最简单,不过这String相关的知识还真是有点难记,这道题难度不大,但是对知识点的灵活应用还是比较高的。
请添加图片描述

  • 27
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 35
    评论
评论 35
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小奕vi

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值