字符串压缩

字符串压缩。利用字符重复出现的次数,编写一种方法,实现基本的字符串压缩功能。比如,字符串aabcccccaaa会变为a2b1c5a3。若“压缩”后的字符串没有变短,则返回原先的字符串。你可以假设字符串中只包含大小写英文字母(a至z)。

示例1:

 输入:"aabcccccaaa"
 输出:"a2b1c5a3"
示例2:

 输入:"abbccd"
 输出:"abbccd"
 解释:"abbccd"压缩后为"a1b2c2d1",比原字符串长度更长。
提示:
字符串长度在[0, 50000]范围内。

解题思路

1.把字符串变成字符数组,定义一个字符出现的次数,初始为12.然后对比相邻的两个字符串是否相等,相等则次数+1,不相等则把字符和次数拼接到目标的字符串后面。
3.最后再把最后出现的字符拼接在最后。
4.比较目标字符串和输入的字符串的长度,选择短的输出即可。
class Solution {
    public String compressString(String S) {
        //字符串长度小于3的情况,直接返回原字符串
        if (S.length() < 3) return S;
        char[] chars = S.toCharArray();
        StringBuilder resultStr = new StringBuilder();
        //计数
        int count = 1;
        //从下标第二位开始
        for (int i = 1; i < chars.length; i++) {
            //和前一位进行比较,如果相等,计数+1
            if (chars[i - 1] == chars[i]) {
                count++;
            } else {
                //如果不想等,加到结果字符串里面,字符+出现的次数
                resultStr.append(chars[i - 1]).append(count);
                //初始化计数器为1
                count = 1;
            }
            //如果最后一个字符,就直接加到最后,加上出现的次数
            if (i == chars.length - 1) {
                resultStr.append(chars[i]).append(count);
            }
        }
        //再比较目标字符的长度和原字符的长度,取短的
        return resultStr.length() >= S.length() ? S : resultStr.toString();
    }
}
class Solution {
    public String compressString(String S) {
        if (S == null || S.length() < 2) return S;//null、""、以及一个字符的情况直接返回
        int orignLen = S.length(), begin = 0, end = 1;
        StringBuilder sb = new StringBuilder();
        while (true) {
            if (end == orignLen) {//当end等于S的长度时,结束
                //避免用类似sb.append(S.charAt(begin)).append(end - begin);这样的写法,我试了下时间直接在原来基础上增加了2ms!!!
                sb.append(S.charAt(begin));
                sb.append(end - begin);
                break;
            } else if (S.charAt(end) == S.charAt(begin)) {//如果相等,那么扩大区间,即end下标右移
                end++;
            } else {//如果不等,说明这个区间已经结束,那么将begin下标位置字符以及区间长度添加到sb
                sb.append(S.charAt(begin));
                sb.append(end - begin);
                begin = end++;//将新区间起始值begin设为end,同时end自增
            }
        }
        return sb.length() < orignLen ? sb.toString() : S;//判断决定返回值
    }
}
class Solution {
    public String compressString(String S) {
        if (S == null || S.length() <= 2) {//如果S的长度<=2 格式化的字符串一定不会比原字符串短
            return S;
        }
        StringBuilder sb = new StringBuilder();
        char[] s = S.toCharArray();//转换成char数组要比字符串索引查找要快一点
        for(int i = 0;i<S.length();++i){
            int count = 0;//计数
            char a = s[i];//查找当前循环字符
            while(i<S.length()&&a == s[i]){//防止索引越界判断是否和目标字符串相等
                count++;
                ++i;//继续遍历下一个字符
            }
            i--;//上一次循环多加了一次,所以需要--
            sb.append(a);
            sb.append(count);
        }
        return sb.length()<S.length() ? sb.toString() : S;
    }
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值