Java stack and map solution with comments
\nclass Solution {\n    public String countOfAtoms(String formula) {\n        \n        /*\n        1. Maintain a stack of freq maps\n        2. for every (, ad
```\nclass Solution {\n    public String countOfAtoms(String formula) {\n        \n        /*\n        1. Maintain a stack of freq maps\n        2. for every (, add the current map to the stack, and refresh the map\n        3. for every ), get the map from the stack, calculate the multiplier and update the frequencies by the multiplier in the map\n        4. for every character, check for the next small characters and calculate the value and add the freq to the map\n        */\n        \n        int i=0;\n        int len = formula.length();\n        Stack<Map<String, Integer>> stack = new Stack<>();\n        Map<String, Integer> map = new HashMap<>();\n        \n        while(i < len) {\n            char c = formula.charAt(i);\n            i++;\n            if (c == \'(\') {\n                // we add the current map to the stack\n                stack.add(map);\n                // and we refresh the map\n                map = new HashMap<>();\n            } else if (c == \')\') {\n                // since we have seen a closed brace we now want to get the multiplier after the closed brace e.g. )20 -> 20 is the multiplier\n                int multiplier = 0;\n                while(i < len && Character.isDigit(formula.charAt(i))) {\n                    multiplier = multiplier * 10 + formula.charAt(i) - \'0\';\n                    i++;\n                }\n                //if we have no digits, the multiplier can simply be 1\n                if (multiplier == 0) {\n                    multiplier = 1;\n                }\n                // this is the current map that we are processing, that has the main frequencies that are to be multiplied\n                Map<String, Integer> temp = map;\n                // this is the initial map\n                /*\n                The example that illustrates this best is Mg(MgO)2\n                in this case, the stack will already contain Mg : 1, and with the (MgO)2, the final value should be Mg : 3\n                so we get the element that is in the stack and add its frequency to the multiplied frequency\n                */\n                map = stack.pop();\n                for(Map.Entry<String,Integer> e: temp.entrySet()) {\n                    String key = e.getKey();\n                    Integer value = e.getValue();\n                    map.put(key, value * multiplier + map.getOrDefault(key, 0));\n                }\n            } else {\n                // this means that the incoming character is now a digit or a number\n                // we are making start as i-1 since the start index of the substring is inclusive\n                // this will help with string such as He, where we need to capture H to go along with e.\n                int start = i-1;\n                while(i < len && Character.isLowerCase(formula.charAt(i))) {\n                    i++;\n                }\n                \n                String s = formula.substring(start, i);\n                int val = 0;\n                while(i < len && Character.isDigit(formula.charAt(i))) {\n                    val = val * 10 + formula.charAt(i) -\'0\';\n                    i++;\n                }\n                \n                if(val == 0)\n                    val = 1;\n                \n                map.put(s, map.getOrDefault(s, 0) + val);\n                \n            }\n        }\n        StringBuilder sb = new StringBuilder();\n        List<String> setOfKeys = new ArrayList<>(map.keySet());\n        Collections.sort(setOfKeys);\n        for(String s: setOfKeys) {\n            sb.append(s);\n            if (map.get(s) > 1) {\n                sb.append(String.valueOf(map.get(s)));\n            }\n        }\n        \n        return sb.toString();\n    }\n}\n```
['Java']