Number of Atoms

This page explains Java solution to problem Number of Atoms using TreeMap data structure.

Problem Statement

Given a chemical formula (given as a string), return the count of each atom.

The atomic element always starts with an uppercase character, then zero or more lowercase letters, representing the name.

One or more digits representing that element's count may follow if the count is greater than 1. If the count is 1, no digits will follow. For example, H2O and H2O2 are possible, but H1O2 is impossible.

Two formulas concatenated together to produce another formula. For example, H2O2He3Mg4 is also a formula.

A formula placed in parentheses, and a count (optionally added) is also a formula. For example, (H2O2) and (H2O2)3 are formulas.

Given a formula, return the count of all elements as a string in the following form: the first name (in sorted order), followed by its count (if that count is more than 1), followed by the second name (in sorted order), followed by its count (if that count is more than 1), and so on.

Example 1:

Input: formula = "H2O"
Output: "H2O"
Explanation: The count of elements are {'H': 2, 'O': 1}.

Example 2:

Input: formula = "Mg(OH)2"
Output: "H2MgO2"
Explanation: The count of elements are {'H': 2, 'Mg': 1, 'O': 2}.

Example 3:

Input: formula = "K4(ON(SO3)2)2"
Output: "K4N2O14S4"
Explanation: The count of elements are {'K': 4, 'N': 2, 'O': 14, 'S': 4}.

Solution

If you have any suggestions in below code, please create a pull request by clicking here.

package com.vc.hard;

import java.util.*;

class NumberOfAtoms {
    public String countOfAtoms(String formula) {
        Queue<Character> q = new LinkedList<>();
        for(int i = 0; i < formula.length(); i++) {
            char ch = formula.charAt(i);
            q.offer(ch);
        }

        StringBuilder sb = new StringBuilder();
        TreeMap<String, Integer> map = helper(q);
        for(Map.Entry<String, Integer> entry: map.entrySet()) {
            sb.append(entry.getKey());
            if(entry.getValue() > 1) sb.append(entry.getValue());
        }
        return sb.toString();
    }

    private TreeMap<String, Integer> helper(Queue<Character> q) {
        TreeMap<String, Integer> map = new TreeMap<>();

        StringBuilder prefix = new StringBuilder();
        int num = 0;
        while(!q.isEmpty()) {
            char ch = q.poll();

            if(ch >= 'A' && ch <= 'Z') {
                if(!prefix.toString().equals("")) map.put(prefix.toString(), map.getOrDefault(prefix.toString(), 0) + (num == 0 ? 1 : num));
                prefix = new StringBuilder(ch + "");
                num = 0;
            }
            else if(ch == '(') {
                TreeMap<String, Integer> subMap = helper(q);
                int factor = 0;
                while(!q.isEmpty() && q.peek() >= '0' && q.peek() <= '9') {
                    char chInternal = q.poll();
                    factor = factor * 10 + (chInternal - '0');
                }
                if(factor == 0) factor = 1;
                for(Map.Entry<String, Integer> entry: subMap.entrySet()) {
                    map.put(entry.getKey(), map.getOrDefault(entry.getKey(), 0) + (factor * entry.getValue()));
                }
            }
            else if(ch >= 'a' && ch <= 'z') prefix.append(ch);
            else if(ch == ')') break;
            else num = num * 10 + (ch - '0');
        }

        if(!prefix.toString().equals("")) map.put(prefix.toString(), map.getOrDefault(prefix.toString(), 0) + (num == 0 ? 1 : num));

        return map;
    }
}

Time Complexity

O(N) Where
N is total number of characters in an input formula

Space Complexity

O(N) Where
N is total number of characters in an input formula