1、题目
2、分析与解答
由括号的表达式问题:用栈处理。因为括号内部也是一个表达式,且要统计原子的数量,因此栈中元素为 Map 集合。
思路:
- 遍历表达式,如果是左括号,则往栈中压入一个空的 map
- 如果不是括号,则读取一个原子名称,如果后面还有数字则读取该数字为原子的个数,否则该原子个数为1,将原子和数字加入栈顶的 map 中。
- 如果是右括号,读取括号后的数字 num,若没有num 则默认为1,弹出栈顶的map,将原子个数都乘以num,存到目前栈顶的map 中。
最后栈顶的map 即为所有原子和其对应的个数。遍历存到数组中。
class Solution {private String formula;private int i;private int n;public String countOfAtoms(String formula) {this.formula = formula;this.i = 0;this.n = formula.length();Deque<HashMap<String,Integer>> deque = new LinkedList<>();deque.push(new HashMap<String,Integer>());while(i < n) {char ch = formula.charAt(i);if(ch == '(') {i++;deque.push(new HashMap<String,Integer>());} else if (ch == ')') {i++;int num = parseNum();Map<String,Integer> popMap = deque.pop();Map<String,Integer> topMap = deque.peek();for(Map.Entry<String,Integer> entry : popMap.entrySet()) {String atom = entry.getKey();int v = entry.getValue();topMap.put(atom,topMap.getOrDefault(atom,0) + v * num);}} else {String atom = parseAtom();int num = parseNum();Map<String,Integer> topMap = deque.peek();topMap.put(atom,topMap.getOrDefault(atom,0) + num);}}Map<String,Integer> popMap = deque.pop();TreeMap<String,Integer> treeMap = new TreeMap<>(popMap);StringBuilder sb = new StringBuilder();for(Map.Entry<String,Integer> entry : treeMap.entrySet()) {sb.append(entry.getKey());int count = entry.getValue();if(count > 1) {sb.append(count);}}return sb.toString();}private String parseAtom() {StringBuilder sb = new StringBuilder();sb.append(formula.charAt(i++));while(i<n && Character.isLowerCase(formula.charAt(i))) {sb.append(formula.charAt(i++));}return sb.toString();}private int parseNum() {if(i == n || !Character.isDigit(formula.charAt(i))) {return 1;}int num = 0;while(i < n && Character.isDigit(formula.charAt(i))) {num = num * 10 + formula.charAt(i++) - '0';}return num;}}
