原子的数量
难度:
标签:
题目描述
代码结果
运行时间: 29 ms, 内存: 0.0 MB
/*
* 题目思路:
* 1. 与上述 Java 实现思路类似,依旧使用栈来处理括号嵌套问题。
* 2. 使用 Java Stream 来对最终结果进行排序和拼接。
*/
import java.util.*;
import java.util.stream.Collectors;
public class AtomCounterStream {
public String countOfAtoms(String formula) {
Map<String, Integer> map = new HashMap<>();
Stack<Map<String, Integer>> stack = new Stack<>();
int i = 0, n = formula.length();
while (i < n) {
if (formula.charAt(i) == '(') {
stack.push(map);
map = new HashMap<>();
i++;
} else if (formula.charAt(i) == ')') {
int iStart = ++i;
int multiplicity = 0;
while (i < n && Character.isDigit(formula.charAt(i))) {
multiplicity = multiplicity * 10 + formula.charAt(i++) - '0';
}
multiplicity = multiplicity == 0 ? 1 : multiplicity;
if (!stack.isEmpty()) {
Map<String, Integer> top = map;
map = stack.pop();
for (String key : top.keySet()) {
map.put(key, map.getOrDefault(key, 0) + top.get(key) * multiplicity);
}
}
} else {
int iStart = i++;
while (i < n && Character.isLowerCase(formula.charAt(i))) i++;
String name = formula.substring(iStart, i);
int multiplicity = 0;
while (i < n && Character.isDigit(formula.charAt(i))) {
multiplicity = multiplicity * 10 + formula.charAt(i++) - '0';
}
multiplicity = multiplicity == 0 ? 1 : multiplicity;
map.put(name, map.getOrDefault(name, 0) + multiplicity);
}
}
return map.entrySet().stream()
.sorted(Map.Entry.comparingByKey())
.map(entry -> entry.getKey() + (entry.getValue() > 1 ? entry.getValue().toString() : ""))
.collect(Collectors.joining());
}
}
解释
方法:
这个题解使用了栈的数据结构来解决问题。它从左到右遍历化学式字符串,对于每个字符进行分情况讨论:
1. 如果是左括号,将当前原子入栈,并清空当前原子。
2. 如果是右括号,将当前原子入栈,并清空当前原子。
3. 如果是数字,判断前一个字符是否也是数字,如果是则继续遍历;否则将当前原子和数字作为一个元组入栈,并清空当前原子。如果前一个字符是右括号,则将数字作为括号内原子的系数,将括号内的所有原子依次出栈并乘以系数后重新入栈。
4. 如果是小写字母,将其加入当前原子的名称中。
5. 如果是大写字母,将当前原子入栈,并将该大写字母作为新的当前原子。
遍历完成后,将栈中的所有原子及其数量存入哈希表中,最后按照字典序将哈希表中的原子拼接成字符串返回。
时间复杂度:
O(nlogn)
空间复杂度:
O(n)
代码细节讲解
🦆
在题解中提到如果当前字符是数字且前一个字符是右括号时,你是如何处理括号内的所有原子乘以系数的?请详细解释这个过程。
▷🦆
为什么在处理大写字母时,如果当前原子不为空,需要先将当前原子入栈再更新当前原子?这样的处理对结果有什么影响?
▷🦆
在解析数字时,你是如何确定数字的完整性并正确解析出整个数字的?这里的逻辑是否能正确处理所有的数字情况,例如连续的数字?
▷🦆
在处理完所有字符后,你是如何从栈中构建哈希表的?请解释这一步骤中的具体逻辑及其对最终结果的影响。
▷相关问题
字符串解码
给定一个经过编码的字符串,返回它解码后的字符串。
编码规则为: k[encoded_string]
,表示其中方括号内部的 encoded_string
正好重复 k
次。注意 k
保证为正整数。
你可以认为输入字符串总是有效的;输入字符串中没有额外的空格,且输入的方括号总是符合格式要求的。
此外,你可以认为原始数据不包含数字,所有的数字只表示重复的次数 k
,例如不会出现像 3a
或 2[4]
的输入。
示例 1:
输入:s = "3[a]2[bc]" 输出:"aaabcbc"
示例 2:
输入:s = "3[a2[c]]" 输出:"accaccacc"
示例 3:
输入:s = "2[abc]3[cd]ef" 输出:"abcabccdcdcdef"
示例 4:
输入:s = "abc3[cd]xyz" 输出:"abccdcdcdxyz"
提示:
1 <= s.length <= 30
s
由小写英文字母、数字和方括号'[]'
组成s
保证是一个 有效 的输入。s
中所有整数的取值范围为[1, 300]