LeetCodes刷题总结9——字符串解码

题目

394. 字符串解码 - 力扣(LeetCode)

题解

题目本身比较好理解,明显是用栈进行处理,但是自我改用Java语言进行刷题以来,发现很多Java基本的结构和API不太熟悉。下面的题解来自官方网站,写的非常细节,总结一下里面出现的细节,权当复习Java基础内容。

class Solution {
    public String decodeString(String s) {
        StringBuilder temp = new StringBuilder();
        int num = 0; // 重复次数
        LinkedList<Integer> nums = new LinkedList<>(); // 记录重复的数字
        LinkedList<String> res = new LinkedList<>(); // 记录当前左括号前的内容
        for(Character c : s.toCharArray()){
            if(c == '['){ //记录[前面的值
                nums.addLast(num);
                res.addLast(temp.toString());
                num = 0;
                temp = new StringBuilder();
            }
            else if(c==']'){
                StringBuilder temp2 = new StringBuilder(); // 处理当前[]中的字符串
                int cur_num = nums.removeLast();
                for(int i=0;i<cur_num;i++) temp2.append(temp);
                temp = new StringBuilder(res.removeLast()+temp2);
            }
            else if(c>='0' && c<='9') // 数字处理
                num = num * 10 +Integer.parseInt(c+"");
            else temp.append(c);
        }
        return temp.toString();
    }
}

先作两点说明:

1.这道题需要记录‘[’前面的数字,但是对于题目提供的字符串中全都是字符,所以要考虑字符和数字之间转换的麻烦事,而且定义一个辅助栈不好存储两种类型。所以作者定义两种栈,一个存‘[’之前解析的数字,一个存字符串。

2.前面说到另一个辅助栈存储字符串,这个可能有点意外,正常不应该是栈里存一个个字符吗?这里作者存的是‘[’之前的字符串,避免来回出栈入栈操作。

比如:给定字符串:3[ab2[bc]],依次遍历,遇到‘[’则将3入数字栈,将""(空串)入字符串栈,再遇到‘[’将2入数字栈,将"ab"入字符串栈,遇到‘]’进行处理再放回栈。

从这两点就已经能看出这份代码的基本细节了。

解析

1.StringBuilder的使用

对于字符串的相关处理,我们肯定要使用StringBuilder这种不创建额外对象的工具。但是这个工具使用也有点奇怪。这里有几处用法:

(1)StringBuilder.append()——添加内容,比较宽松,可接收大部分基本数据类型、String、char[]等等,甚至接收StringBuilder。

StringBuilder sb = new StringBuilder();
sb.append(8).append("乘以").append(6.6).append('=').append(true);
sb.append(new StringBuilder("!!!"));
System.out.println(sb); // 输出结果为:8乘以6.6=true!!!

(2)StringBuilder和String类型的转换

StringBuilder sb = new StringBuilder();
String s = sb.toString(); // StringBuilder转String
StringBuilder sb2 = new StringBuilder(s); // String转StringBuilder

(3)清空 StringBuilder

可能一想就是StringBuilder.clear(),哈哈,可惜没有这个API,可以选择重新new StringBuilder(),这里代码的使用就是这样。

StringBuilder temp = new StringBuilder();
temp.append("hello");
temp = new StringBuilder(); // 清空StringBuilder

(4)复制字符串n次

本来想到的是String+=这种,但是已经在用StringBuilder处理了,转成String再转回来更麻烦。这里是重新new StringBuilder(),然后循环添加之前的StringBuilder。

StringBuilder temp2 = new StringBuilder(); // 处理当前[]中的字符串
int cur_num = nums.removeLast();
for(int i=0;i<cur_num;i++) temp2.append(temp); // 复制字符串n次

2.栈的使用

Java中是有栈的对象的,即Stack对象,但是一般不用,而是使用Collection集合对象下的一些对象,其实这些也满足栈的功能,哪怕定义一个String进行操作也有栈的先入后出特性。这里使用的是LinkedList集合定义两个辅助栈。

(1)包装类

List集合包括ArrayList和LinkedList两种,如果要定义操作基本数据类型的List,就要使用包装类。如int对应Integer类,char对应Character类。

LinkedList<Integer> nums = new LinkedList<>(); // 记录重复的数字

(2)LinkedList相关API

LinkedList.addLast()——元素添加到尾部

nums.addLast(num);

LinkedList.removeLast()——删除并返回最后一个元素,注意区别remove()

int cur_num = nums.removeLast();

3.遍历字符串

遍历一个String有几种常用办法:

String str="HelloWorld";

// 法一
for(int i=0;i < str.length();i++) {
	 System.out.println(str.charAt(i)); 
}

//法二
for(int i=0;i < str.length();i++) {
	 System.out.println(str.substring(i,i+1));  
}

//法三
char[]  c = str.toCharArray();
for(int i=0;i < c.length;i++) {
	System.out.println(c[i]);
}

这里为了更好获得每一个字符,作者的方式很巧妙,先将s变为字符数组,再进行增强式for循环:

for(Character c : s.toCharArray()){}

4.对于数字的处理

要注意一点,就是题目中并没有说数字一定是个位数,也就是可能有"32[as]"这样的情况。‘3’和‘2’都是字符,那怎么拿到数字32呢?

作者使用Integer类的parseInt方法处理,但是这个方法参数是字符串?字符变为字符串使用字符+""的方式,即parseInt(字符+"")就得到字符对应的数字了。

又可能为多位数字,使用num=num*10的方式计算,数字处理完毕之后一定为‘[’,直接进行入栈,是不是很巧妙?

else if(c>='0' && c<='9') // 数字处理
                num = num * 10 +Integer.parseInt(c+"");

总结

没想到一个简单的题目蕴含这么多东西,总结下来学会很多。这一份题解代码还有很多细节,只能说多刷多总结,Java基础才能牢固。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值