class Solution { public String countOfAtoms(String formula) { Map<String, Integer> map = new TreeMap<>(); dfs(formula.toCharArray(), 0, map); StringBuilder sb = new StringBuilder(); for(Map.Entry<String, Integer> entry : map.entrySet()) { sb.append(entry.getKey() + (entry.getValue() > 1 ? entry.getValue() : "")); } return sb.toString(); } private int parseDigit(char[] chars, int i, StringBuilder sb) { while(i < chars.length && Character.isDigit(chars[i])) { sb.append(chars[i++]); } if(sb.length() == 0) { sb.append(1); } return i; } private int parseAtom(char[] chars, int i, StringBuilder sb) { sb.append(chars[i++]); while(i < chars.length && Character.isLowerCase(chars[i])) { sb.append(chars[i++]); } return i; } private int dfs(char[] chars, int i, Map<String, Integer> map) { while(i < chars.length) { if(chars[i] == ')') { return i + 1; }else if(chars[i] == '(') { Map<String, Integer> innerMap = new HashMap<>(); i = dfs(chars, i + 1, innerMap); StringBuilder sb = new StringBuilder(); i = parseDigit(chars, i, sb); int cnt = Integer.parseInt(sb.toString()); innerMap.forEach((key, value) -> { map.put(key, map.getOrDefault(key, 0) + value * cnt); }); }else { StringBuilder atom = new StringBuilder(); StringBuilder digit = new StringBuilder(); i = parseAtom(chars, i, atom); i = parseDigit(chars, i, digit); map.put(atom.toString(), map.getOrDefault(atom.toString(), 0) + Integer.parseInt(digit.toString())); } } return i; }}