剑指offer05(Java)-替换空格(简单)

题目:

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

 

示例 1:

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

限制:

  • 0 <= s 的长度 <= 10000

来源:力扣(LeetCode)
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

解题思路:

参考题解:代码随想录

方法一:使用一个新的对象StringBuffer,复制 s,复制的过程对其判断,是空格则替换,否则直接复制。

Java StringBuffer toString() 方法返回此字符序列的字符串表示形式。StringBuffer 类的一个对象表示一个字符序列。toString() 方法将此序列转换为字符串。

 1 class Solution {
 2     public String replaceSpace(String s) {
 3         //特判
 4         if (s == null || s.length() == 0) return s;
 5         StringBuffer sb = new StringBuffer();
 6         for (int i = 0; i < s.length(); i++){
 7             if (s.charAt(i) == ' '){
 8                 sb.append("%20");
 9             }else{
10                 sb.append(s.charAt(i));
11             }
12         }
13         return sb.toString();
14     }
15 }

方法二:双指针

需要将空格替换为 "%20" ,字符串的总字符数增加,因此需要扩展原字符串 s 的长度,计算公式为:新字符串长度 = 原字符串长度 + 2 * 空格个数。图片来源:K神老师

 思路:

  • 初始化:字符串 s 的长度 len,进行判空 ;
  • 增加长度:定义一个可变字符序列StringBuffer,如果遇到原字符串中的一个空格,就将StringBuffer添加两个空格,遍历完后,如StringBuffer中没有空格,则直接返回s,否则将空格数添加至原字符后面。
  • 倒序遍历修改:将原字符串变为字符串数组,i 指向原字符串尾部元素len -1, j 指向新字符串尾部元素;当 i = j 时跳出(代表左方已没有空格,无需继续遍历);
    • 当 s[i] 不为空格时:执行 s[j] = s[i] , j--;
    • 当 s[i] 为空格时:挨个添加字符-- "%20" ;
    • 上两步都判断后执行:i--;
  • 返回值:修改后的字符串数组转为字符串返回 ;
 1 class Solution {
 2     public String replaceSpace(String s) {
 3         //特判
 4         int len = s.length();
 5         if (len == 0 || s == null) return s;
 6         //统计空格数量,并扩充2倍
 7         StringBuffer sb = new StringBuffer();
 8         for (int i = 0; i < len; i++){
 9             if (s.charAt(i) == ' ') sb.append("  ");
10         }
11         //如果sb没有空格
12         if (sb.length() == 0) return s;
13         //将空格加到原字符后面
14         s += sb.toString();
15         //将字符串转为字符数组
16         char[] str = s.toCharArray();
17         //i指向原字符串末尾,j指向新字符串末尾
18         int i = len - 1, j = str.length - 1;
19         while (i != j){
20             if (str[i] != ' '){
21                 str[j] = str[i];
22                 j--;
23             }else{
24                 str[j--] = '0';
25                 str[j--] = '2';
26                 str[j--] = '%';
27             }
28             i--;
29         }
30         return new String(str);
31     }
32 }

注意:两个地方

 ①为什么i--要写在后面而不是写在j--后面?

 这时“%20”已经添加完毕,i没变仍为空格,j位置又会开始加“%20”,i就一直不动,导致违背题意(可以自己在草稿纸上推一下),故i--需要写在后面,保证i一直在往前移动。

②为什么最后一个j也要减减?

j--:表示先使用后减。最后一个j使用后再减1,是为了跳到下一个位置,后续可以放其他字符。

小知识:

StringBuilder类 和 StringBuffer类:

  • StringBuilder: 可变的字符序列 , 线程不安全的,效率高,底层是 char[]数组 存储

  • StringBuffer : 可变的字符序列 , 线程安全的,效率低 ,底层是 char[]数组 存储

posted on 2023-04-09 11:32  我不想一直当菜鸟  阅读(112)  评论(0编辑  收藏  举报