Skip to content

Instantly share code, notes, and snippets.

@jianminchen
Created February 1, 2018 20:54
Show Gist options
  • Save jianminchen/702f0bcf4430f0fd6e90455ccb64862a to your computer and use it in GitHub Desktop.
Save jianminchen/702f0bcf4430f0fd6e90455ccb64862a to your computer and use it in GitHub Desktop.
Leetcode 726 - number of atoms -
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace NumberOfAtoms
{
class Program
{
static void Main(string[] args)
{
}
/// <summary>
/// code review on the discussion
/// https://discuss.leetcode.com/topic/110438/c-solution
/// Feb. 1, 2018
/// Iterative solution - it works, but need to make it simple one using recursive solution.
///
/// </summary>
/// <param name="formula"></param>
/// <returns></returns>
public static string CountOfAtoms(string formula)
{
var result = string.Empty;
// "K4(ON(SO3)2)2"
int openBrackets = 0;
var dict = new Dictionary<string, int>();
var names = new Stack<string>();
var values = new Stack<int>();
var length = formula.Length;
for (int index = 0; index < length; index++)
{
var atom = string.Empty;
var current = formula[index];
var isOpenBracket = current == '(';
var isCloseBracket = current == ')';
var isLetter = char.IsLetter(current);
var isUpper = char.IsUpper(current);
//(H2O)2
if (isOpenBracket)
{
openBrackets++;
names.Push("(");
values.Push(-1);
}
else if (isCloseBracket)
{
openBrackets--;
// read the number if there is one after ')'
var extractions = paseNumber(formula, index);
atom += extractions[0];
index = Convert.ToInt32(extractions[1]);
int multiplication = atom.Length > 0 ? int.Parse(atom) : 1;
if (openBrackets > 0)
{
var childNames = new Stack<string>();
var childValues = new Stack<int>();
while (names.Count > 0 && names.Peek() != "(")
{
childNames.Push(names.Pop());
childValues.Push(values.Pop() * multiplication);
}
names.Pop();
values.Pop();
// move child stacks to parent stacks
while (childNames.Count > 0)
{
names.Push(childNames.Pop());
values.Push(childValues.Pop());
}
}
else
{
while (names.Count > 0 && names.Peek() != "(")
{
if (dict.ContainsKey(names.Peek()))
{
dict[names.Pop()] += multiplication * values.Pop();
}
else
{
dict.Add(names.Pop(), multiplication * values.Pop());
}
}
names.Pop();
values.Pop();
}
}
else if (isLetter && isUpper)
{
atom += current;
index++;
while (index < length && char.IsLower(formula[index]))
{
atom += formula[index];
index++;
}
var extractions = paseNumber(formula, index);
string value = extractions[0];
index = Convert.ToInt32(extractions[1]);
int m = value.Length > 0 ? int.Parse(value) : 1;
if (openBrackets > 0)
{
names.Push(atom);
values.Push(m);
}
else
{
if (dict.ContainsKey(atom))
{
dict[atom] += m;
}
else
{
dict.Add(atom, m);
}
}
}
}
while (names.Count > 0)
{
if (dict.ContainsKey(names.Peek()))
{
dict[names.Pop()] += values.Pop();
}
else
{
dict.Add(names.Pop(), values.Pop());
}
}
dict.OrderBy((x) => x.Key).ToList().ForEach(y =>
{
result += y.Key;
if (y.Value > 1)
{
result += y.Value;
}
});
return result;
}
/// <summary>
/// extract a number
/// </summary>
/// <param name="formula"></param>
/// <param name="index"></param>
/// <returns></returns>
private static string[] paseNumber(string formula, int index)
{
string value = "";
// repeat the code - extract a function
while (index < formula.Length && char.IsDigit(formula[index]))
{
value += formula[index];
index++;
}
index--;
return new string[] {value, index.ToString()};
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment