Leetcode 726 原子的数量 【栈+散列表】

题目:

如果以化学专业名字解释,一句话概括:

输入结构简式,输出分子式(元素顺序按字母顺序)

例子:

输入输出
H2OH2O
Mg(OH)2H2MgO2
K4(ON(SO3)2)2K4N2O14S4
Be32Be32

题解:

统计各元素总数。遇到括号,要把括号内的数量乘以括号右边的系数,括号可以嵌套。

用到两种数据结构:

散列表:用于存放元素名及其数量

栈:遇到左括号时,当前散列表入栈,用一个新的空表处理当前括号内的内容

(可以用递归调用代替栈)

编码实现思路:

不含括号的情况下,每解出一个元素及其数量,计算累积和可以抽象成:

累积和 += 当前元素 * 该元素数量

含括号的情况下,右括号出栈,出栈后可以抽象成:

累积和 += 括号内统计和 * 括号外数量

——两种情况下表达式一样,可以构建一个专门的处理函数,见源码__addtoDict()

Python源码:

import collections

class Solution(object):

    def __addAtomtoDict(self, d, atom, count):
        if d.__contains__(atom):
            d[atom] = d[atom] + count
        else:
            d[atom] = count
    def __addDicttoDict(self, d, d2, multiple):
        for atom in d2.keys():
            self.__addAtomtoDict(d, atom, d2[atom] * multiple)
    def __addtoDict(self, d, elem, cnt):
        if cnt == 0:
            cnt = 1
        if isinstance(elem, dict):
            self.__addDicttoDict(d, elem, cnt)
        elif isinstance(elem, str):
            self.__addAtomtoDict(d, elem, cnt)
        else:
            pass

    def countOfAtoms(self, formula):
        i = 0
        stack = collections.deque()
        currDict = {}
        currElem = None
        currCnt = 0
        for c in formula:
            if c >= '0' and c <= '9':
                currCnt = currCnt * 10 + ord(c) - ord('0')
            elif c >= 'a' and c <= 'z':
                currElem += c
                # 遇到新元素,或左右括号,都把curr的元素统计入散列表Dict
            elif c >= 'A' and c <= 'Z':
                self.__addtoDict(currDict, currElem, currCnt)
                currElem = c
                currCnt = 0
            elif c == '(':
                self.__addtoDict(currDict, currElem, currCnt)
                # 遇到左括号,把当前散列表入队,再开一个空散列表
                stack.append(currDict)
                currDict = {}
                currElem = None
                currCnt = 0
            else: # ')'
                self.__addtoDict(currDict, currElem, currCnt)
                # 遇到右括号,弹栈
                currElem = currDict
                currCnt = 0
                currDict = stack.pop()
        # 最后,把缓冲区的加入字典
        self.__addtoDict(currDict, currElem, currCnt)

        ans = ""
        atoms = list(currDict.keys())
        atoms.sort()
        for a in atoms:
            ans += a
            if currDict[a] > 1:
                ans += str(currDict[a])
        return ans



if __name__ == "__main__":
    print(Solution().countOfAtoms("H2O"))
    print(Solution().countOfAtoms("Mg(OH)2"))
    print(Solution().countOfAtoms("K4(ON(SO3)2)2"))
    print(Solution().countOfAtoms("Be32"))

执行用时:40 ms, 在所有 Python3 提交中击败了75.00%的用户

内存消耗:15.1 MB, 在所有 Python3 提交中击败了26.74%的用户

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值