剑指offer面试题5(java版):替换空格

面试题5:替换空格

题目描述

请实现一个函数,将一个字符串中的每个空格替换成“%20”。例如,当字符串为We Are Happy.则经过替换之后的字符串为We%20Are%20Happy。

第三次做; 延长原始StringBuffer的长度, 时间复杂度O(N), 空间复杂度最差是O(N), 比如说原始字符串全是空格; 核心: 长度扩展多少? 不是3spaceCount, 要考虑到原始的空格, 每个空格对应两个新的位置, 所以一共扩展2spaceCount的长度
public class Solution {
    public String replaceSpace(StringBuffer str) {
        //input check
        if(str==null)
            return "";
        if(str.length()==0)
            return str.toString();
        //
        int spaceCount = 0, n = str.length();
        for(int i=0; i<n; i++){
            if(str.charAt(i)==' ')
                spaceCount++;
        }
        //扩展长度; 核心: 长度增加多少? 不是
        str.setLength(n+2*spaceCount);
        //从后往前更新str
        int left = n-1, right = str.length()-1;
        while(left>=0 && right>=0){
            char ch = str.charAt(left);
            if(ch != ' '){
                str.setCharAt(right--, ch);
                left--;
            }
            else{
                str.setCharAt(right--, '0'); //是char,不是String
                str.setCharAt(right--, '2');
                str.setCharAt(right--,'%');
                left--;
            }
        }
        return str.toString();
    }
}
第三次做; 创建一个新的StringBuilder, 时间复杂度O(N), 空间复杂度O(N)
public class Solution {
    public String replaceSpace(StringBuffer str) {
        //input check
        if(str==null || str.length()==0)
            return str.toString();
        //从后往前
        StringBuilder sb = new StringBuilder();
        for(int i=0; i<str.length(); i++){
            char ch = str.charAt(i);
            if(ch==' ')
                sb.append("%20");
            else
                sb.append(ch);
        }
        return sb.toString();
    }
}

思路

  1. 先明确需求.如果实在原来的字符串上进行替换,就有可能覆盖修改在该字符串后面的内存; 如果是创建新的字符串并在新的字符串上进行替换,那么就可以自己分配足够多的的内存
  2. 需求: 返回一个新字符串
  3. 创建一个新StringBuffer, 逐个复制, 遇到空格时做特殊处理, 用if else就可以了
  4. 期初犯错了,StringBuffer(newLen)并不会创建一个长为newLen的字符串,而是创建一个长为0的字符串

复杂度

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

反思

选择从前往后复制还是从后往前复制,要根据具体情况决定. 本题可以确定新字符串的长度, 所以从前往后或者从后往前都行

第二次做, 直接在原输入上操作; 注意setLength的大小; setCharAt(index, char); 一个指针倒序遍历原输入, 另一个指针倒序遍历改变长度后的原输入
public class Solution {
    public String replaceSpace(StringBuffer str) {
        if(str==null || str.length()==0)
            return str.toString();
        //
        //直接在原输入上进行修改
        int spaceCount = 0;
        for(int i=0; i<str.length(); i++){
            if(str.charAt(i)==' ')
                spaceCount++;
        }
        int i = str.length()-1;
        //set new length
        str.setLength(str.length()+spaceCount*2);
        //modify reversely
        for(int j=str.length()-1; j>=0&&i>=0; j--,i--){
            if(str.charAt(i)==' '){
                str.setCharAt(j--,'0');
                str.setCharAt(j--,'2');
                str.setCharAt(j, '%');
            }
            else
                str.setCharAt(j, str.charAt(i));
        }
        return str.toString();
    }
}
空间复杂度O(N)的解法
public class Solution {
    public String replaceSpace(StringBuffer str) {
        //input check
        if(str==null) return null;
        //
        int len = str.length();
        StringBuilder sb = new StringBuilder();
        for(int i=0; i<len; i++){
            if(str.charAt(i) == ' ')
                sb.append("%20");
            else
                sb.append(str.charAt(i));
        }
        return sb.toString();
    }
}
空间复杂度O(1)的解法
public class Solution {
    public String replaceSpace(StringBuffer str) {
        //input check
        if(str==null)return null;
        //
        int len = str.length();
        int spaceCount = 0;
        for(int i=0; i<len; i++)
            if(str.charAt(i)==' ')
                spaceCount++;
        int newLen = len + 2*spaceCount;
        //调整str长度
        str.setLength(newLen);
        //从后往前调整str中各个char的位置
        int newI=newLen-1, oldI=len-1;
        //循环时:仍有空格位处理,没有空格时newI==oldI
        while(newI>oldI){
            if(str.charAt(oldI)==' '){
                str.setCharAt(newI--, '0');
                str.setCharAt(newI--, '2');
                str.setCharAt(newI--, '%');
            }
            else{
                str.setCharAt(newI--,str.charAt(oldI));
            }
            oldI--;
        }
        return str.toString();
    }
}

for 循环版本; 要适应for循环中有两个条件的写法

public class Solution {
    public String replaceSpace(StringBuffer str) {
        //input check
        if(str==null)return null;
        //
        int len = str.length();
        int spaceCount = 0;
        for(int i=0; i<len; i++)
            if(str.charAt(i)==' ')
                spaceCount++;
        int newLen = len + 2*spaceCount;
        //调整str长度
        str.setLength(newLen);
        //从后往前调整str中各个char的位置
        int newI=newLen-1, oldI=len-1;
        //循环时:仍有空格位处理,没有空格时newI==oldI
        for(; newI>oldI; oldI--){
            if(str.charAt(oldI)==' '){
                str.setCharAt(newI--, '0');
                str.setCharAt(newI--, '2');
                str.setCharAt(newI--, '%');
            }
            else{
                str.setCharAt(newI--,str.charAt(oldI));
            }
        }
        return str.toString();
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值