[JavaScript 刷题] 栈 - 原子的数量, leetcode 726

Posted GoldenaArcher

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[JavaScript 刷题] 栈 - 原子的数量, leetcode 726相关的知识,希望对你有一定的参考价值。

[javascript 刷题] 栈 - 原子的数量, leetcode 726

github repo 地址: https://github.com/GoldenaArcher/js_leetcode,Github 的目录 大概 会更新的更勤快一些。

题目地址:

题目

如下:

Given a string formula representing a chemical formula, 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 are 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.

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.

The test cases are generated so that all the values in the output fit in a 32-bit integer.

解题思路

解题思路其实和 [JavaScript 刷题] 栈 - 字符串解码, leetcode 394 这道题基本一致,也是采取了两个 stack 的方法去解题,内部的 stack 用来承接括号内的部分。

比起 394 题,这里需要多处理的几个部分有:

  1. 元素可能会出现一个字母,如 H, O,或两个字母,如 Mg, Na 这种情况

    处理方式:正则 /[A-Z]/ 判断第一个字符,正则 /[a-z]/ 判断第二个字符

  2. 括号的处理

    这里和 394 的处理几乎没有区别就是了

  3. 字符串全摊开会导致 Time Limit Exceed

    这个时候做个乘法就好,394 的题目规定需要将数组展开,这里可以在遇到 ) 后读取下一个数字,并且将其与括号内的记数相乘即可

    如:"K4(ON(SO3)2)2"

    在遇到第一个 ) 之前栈中的内容为:K, 4, (, O, N, (, S, O, 3,在遇到第一个 ) 需要读取下一个数字 num1,这里是 2。如果 ) 下一个字符不是数字,则使用 1 代替。

    进行弹栈操作,如果第一个弹出的是数字,则将元素也弹出。完成弹栈测操作将元素推入临时栈中。这里第一个进行压栈操作的为 O3 x 2(num1)

    S 没有对应的数字,只需要将 S1(num1) 压入栈中即可。

    完成操作后栈中保存的数据为:K, 4, (, O, N, S, 1, O, 6,随后重复进行操作即可。

可以省去对 stack 进行遍历的一个方法就是使用递归+返回 map 实现,这个部分感兴趣的可以自己试一下,大概逻辑大差不差了。

使用 JavaScript 解题

代码比较丑,将就着看就好了。

/**
 * @param string formula
 * @return string
 */
var countOfAtoms = function (formula) 
  if (!formula || !formula.length) return "";

  const stack = [];

  const getAtom = (ch1, ch2) => 
    if (ch2 && /[a-z]/.test(ch2)) return ch1 + ch2;
    return ch1;
  ;

  const isNum = (ch) => /[0-9]/.test(ch);

  for (let i = 0; i < formula.length; i++) 
    const ch = formula[i];
    if (/[A-Z]/.test(ch)) 
      const atom = getAtom(ch, formula[i + 1]);
      i += atom.length - 1;
      stack.push(atom);
     else if (isNum(ch)) 
      let num = ch;
      while (isNum(formula[++i])) num = num * 10 + +formula[i];
      i--;
      stack.push(num);
     else if (ch === ")") 
      const tempStack = [];
      let num = 0;
      if (isNum(formula[i + 1])) 
        num = formula[++i];
        while (isNum(formula[++i])) num = num * 10 + +formula[i];
        i--;
      

      num = num || 1;

      while (stack[stack.length - 1] !== "(") 
        const el = stack.pop();
        if (isNum(el)) 
          const atom = stack.pop();
          tempStack.push(atom, el * num);
         else 
          tempStack.push(el, num);
        
      

      stack.pop(); // remove (

      stack.push(...tempStack);
     else 
      stack.push(ch);
    
  

  const map = new Map();

  for (let i = 0; i < stack.length; i++) 
    const atom = stack[i];
    let num = 1;
    if (isNum(stack[i + 1])) num = stack[++i];

    if (map.has(atom)) map.set(atom, +map.get(atom) + +num);
    else map.set(atom, num);
  

  const keys = [...map.keys()].sort((a, b) => (a < b ? -1 : 1)),
    res = [];

  for (let i = 0; i < keys.length; i++) 
    res.push(keys[i]);
    const num = map.get(keys[i]);
    if (num > 1) res.push(num);
  

  return res.join("");
;

以上是关于[JavaScript 刷题] 栈 - 原子的数量, leetcode 726的主要内容,如果未能解决你的问题,请参考以下文章

[JavaScript 刷题] 栈 - 原子的数量, leetcode 726

[JavaScript 刷题] 栈 - 最小栈, leetcode 155

[JavaScript 刷题] 栈 - 最小栈, leetcode 155

[Hdfs] lc726. 原子的数量(模拟+dfs+栈+字符串处理+好题)

[JavaScript 刷题] 栈 - 有效的括号, leetcode 20

[JavaScript 刷题] 栈 - 有效的括号, leetcode 20