题目描述:
示例 1:
示例 2:
示例 3:
示例 4:
思路:
遍历formula,如果当前元素是"(",则创建一个map,push到栈中.
遍历formula,如果当前元素是")",则判断下一个元素是否数字
- 不是数字,num默认为1
- 是数字,则把数字全部获取出来赋值给num,例如:"H(M20)32K",则num=32,也就是取到下一个不是数字的元素为止。弹出栈顶map_pop,以及栈顶的下一个map_peek.遍历map_pop,使用num * map_pop的所有value,再存入到map_peek,如果map_peek中存在相同key,则相加之后再存入.
例如:stack[map_peek([H,1]), map_pop([H,2], [M,1])], num = 2;执行完成后stack[map_peek([H,5], [M,2])]
- 遍历formula,如果当前元素不是"("和")",则判断下一个字符是否是小写字符,如果是的话,则一直遍历取到下一个大写字符为止。例如:"HgM3",Hg需要作为一个整体被取出,作为key存入栈顶的map.
说明:
代码实现:
class Solution {
int n = 0;
int i = 0;
String str = "";
public String countOfAtoms(String formula) {
n = formula.length();
i = 0;
str = formula;
Stack<Map<String, Integer>> stack = new Stack();
stack.push(new HashMap<String, Integer>());
while (i < n) {
if (str.charAt(i) == '(') {
i++;
stack.push(new HashMap<String, Integer>());
} else if (str.charAt(i) == ')') {
i++;
int num = 0;
if(i == n || !Character.isDigit(str.charAt(i))) {
num = 1;
}
while (i < n && Character.isDigit(str.charAt(i))) {
num = num * 10 + Integer.valueOf(str.charAt(i++) - '0');
}
Map<String, Integer> cur = stack.pop();
Map<String, Integer> pre = stack.peek();
for (Map.Entry<String, Integer> entryCur : cur.entrySet()) {
String curKey = entryCur.getKey();
Integer curValue = entryCur.getValue();
pre.put(curKey, pre.getOrDefault(curKey, 0) + curValue * num);
}
} else {
StringBuilder sb = new StringBuilder();
sb.append(str.charAt(i++));
while (i < n && Character.isLowerCase(str.charAt(i))) {
sb.append(str.charAt(i++));
}
int num = 0;
if(i == n || !Character.isDigit(str.charAt(i))) {
num = 1;
}
while (i < n && Character.isDigit(str.charAt(i))) {
num = num * 10 + Integer.valueOf(str.charAt(i++) - '0');
}
Map<String, Integer> peek = stack.peek();
peek.put(sb.toString(), peek.getOrDefault(sb.toString(), 0) + num);
}
}
Map<String, Integer> pop = stack.pop();
TreeMap<String, Integer> treeMap = new TreeMap(pop);
StringBuffer sb = new StringBuffer();
for (Map.Entry<String, Integer> entry : treeMap.entrySet()) {
String atom = entry.getKey();
int count = entry.getValue();
sb.append(atom);
if (count > 1) {
sb.append(count);
}
}
return sb.toString();
}
}