# 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) {
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