博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
算法48---原子的数量【栈】
阅读量:6230 次
发布时间:2019-06-21

本文共 2835 字,大约阅读时间需要 9 分钟。

一、题目:原子的数量

给定一个化学式formula(作为字符串),返回每种原子的数量。

原子总是以一个大写字母开始,接着跟随0个或任意个小写字母,表示原子的名字。

如果数量大于 1,原子后会跟着数字表示原子的数量。如果数量等于 1 则不会跟数字。例如,H2O 和 H2O2 是可行的,但 H1O2 这个表达是不可行的。

两个化学式连在一起是新的化学式。例如 H2O2He3Mg4 也是化学式。

一个括号中的化学式和数字(可选择性添加)也是化学式。例如 (H2O2) 和 (H2O2)3 是化学式。

给定一个化学式,输出所有原子的数量。格式为:第一个(按字典序)原子的名子,跟着它的数量(如果数量大于 1),然后是第二个原子的名字(按字典序),跟着它的数量(如果数量大于 1),以此类推。

示例 1:

输入: formula = "H2O"输出: "H2O"解释: 原子的数量是 {'H': 2, 'O': 1}。

示例 2:

输入: formula = "Mg(OH)2"输出: "H2MgO2"解释: 原子的数量是 {'H': 2, 'Mg': 1, 'O': 2}。

示例 3:

输入: formula = "K4(ON(SO3)2)2"输出: "K4N2O14S4"解释: 原子的数量是 {'K': 4, 'N': 2, 'O': 14, 'S': 4}。

注意:

  • 所有原子的第一个字母为大写,剩余字母都是小写。
  • formula的长度在[1, 1000]之间。
  • formula只包含字母、数字和圆括号,并且题目中给定的是合法的化学式。

 

思路:时间O(n),空间O(n)

采用一个栈,存储数字

从后往前遍历: for s in formula[::-1]

(1)遇到数字,则令 num = 数字* (10^i ),【存在连续两个数字出现,如“Be32”】故采用 i 来判断,如果前面一个字母不是数字,则 i = 0, 否则,i+=1。

即 if s.isdigit():

  num += int(s)*(10**i)

  i += 1

(2)遇到 ')'则将 num数字加入栈 stack 中,因为数字存在两种情况,【如‘H4(CO3)2’,像3和4是不用存到栈中,2要存进stack中】,故遇到 )才将num存进stack中。然后令num=0,i=0

即 if s == ')':

  stack.append(num)

  num = i = 0

(3)遇到‘(’,则将栈最后一个元素删除,因为【‘H2(CO3(CaO)4)2’】,此时stack中应该为【4,2】,遇到第一个(将2弹出,因为CO3对应的系数应为2,而CaO对应的系数为4*2=8。

即 if s == '(':

  stack.pop()

  num = i = 0

(4)大写字母,则将完整字母,【‘Mg'】存入字典中,其对应的系数为栈中所有数相乘的结果,如果字典中原来存在的话就将原来的系数加上,

其余条件初始化:num = i = 0,string = ’‘【小写字母】,count = 1【栈中所有的数相乘结果】

即 if s.isupper():

  string += s

       count = num if num else 1  #像【‘H2(CO3(CaO)4)2’】count=3,再与栈中所有数相乘
#栈中所有数相乘      

  for m in stack:  

         count *= m

# 将结果存入字典中

       if string[::-1] in dic:
             dic[string[::-1]] += count
        else:
             dic[string[::-1]] = count

#初始化

        string = ''
        count,num,i= 1,0,0

(5)小写字母,与之前的字母相加起来

即 if s.islower():

  string += s

 

代码:

def countOfAtoms(self, formula):        """        :type formula: str        :rtype: str        """        if not formula:            return ""        stack = []        dic = {}        string = ''        count,num,i = 1,0,0        for s in formula[::-1]:            if s.isdigit():                num += int(s)*(10**i)                i+=1            elif s == ')':                stack.append(num)                num = 0                i=0            elif s == '(':                stack.pop()                i ,num= 0,0            elif s.isupper():                string += s                 count = num if num else 1                for m in stack:                    count *= m                if string[::-1] in dic:                    dic[string[::-1]] += count                else:                    dic[string[::-1]] = count                string = ''                count,num = 1,0                i = 0            elif s.islower():                string += s        sort = sorted(dic.items(),key = lambda x:x[0])        res = ''        for item in sort:            res += item[0]            if item[1]>1:                res += str(item[1])        return res

 

转载于:https://www.cnblogs.com/Lee-yl/p/9948726.html

你可能感兴趣的文章
《3D打印:正在到来的工业革命》一一1.4 先行者们在做什么
查看>>
TimeTraveler. - 朝花夕拾,拾了又拾
查看>>
spring之Bean的生命周期
查看>>
如何打造支撑百万用户的分布式代码托管平台
查看>>
《机器人操作系统ROS原理与应用》——第1章 智能机器人及其发展概述
查看>>
《Adobe Illustrator CC 2014中文版经典教程(彩色版)》—第2课2.5节对象的排列
查看>>
Android 数据库框架ormlite
查看>>
零基础学习贴:如何收取短信回复消息
查看>>
网鱼网咖-利用数加快速搭建大数据平台,极致洞察,为客户带来从所未有的体验。...
查看>>
保护App重要数据,防止Cycript/Runtime修改
查看>>
iperf 测试网络性能指标
查看>>
windows下安装mysql压缩包版[转]
查看>>
Emacs常用命令汇总
查看>>
从传统IT快速走向公共云计算
查看>>
小菜一步一步学数据结构之(一)基本概念和术语
查看>>
《Redis官方教程》Redis集群规范
查看>>
Mac下没有make命令解决办法
查看>>
DLL中传递STL参数
查看>>
postgresql 范围类型
查看>>
隐藏 tengine 和 tomcat 版本号
查看>>