1. 程式人生 > >LeetCode-726. 原子的數量(python2)

LeetCode-726. 原子的數量(python2)

題目連結:

726.原子數量

題目難度:困難 

題目描述:

給定一個化學式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只包含字母、數字和圓括號,並且題目中給定的是合法的化學式。

解題思路與解題程式碼:

# -*- coding: UTF-8 -*-
class Solution(object):
    def countOfAtoms(self, formula):

        stack = list()
        # 第一步將每個元素、數字、括號獨立出來,也就是說有的元素有兩個字母組成,有的數字是10以上的
        # 因此要把他們組合
        i = 0
        n = len(formula)
        while i < n:
            if formula[i].isalpha():
                if formula[i].islower():
                    c = stack.pop()
                    c = c + formula[i]
                    stack.append(c)
                else:
                    stack.append(formula[i])
                i += 1
            elif formula[i] == '(':
                stack.append(formula[i])
                i += 1

            elif formula[i] == ')':
                stack.append(formula[i])
                i += 1
            else:
                num_str = formula[i]
                i += 1
                while i < n and formula[i].isdigit():
                    num_str += formula[i]
                    i += 1
                stack.append(num_str)
        # 組合結果如下
        # print stack
        # ['K', '4', '(', 'O', 'N', '(', 'S', 'O', '3', ')', '2', ')', '2']

        # 第二步 有的元素只有一個,因此要把1補齊
        i = 0
        m = len(stack)-1
        tmp_stack = list()
        for i in range(m):
            tmp_stack.append(stack[i])
            if stack[i].isalpha():
                if not stack[i+1].isdigit():
                    tmp_stack.append("1")

        tmp_stack.append(stack[m])
        if stack[m].isalpha():
            tmp_stack.append("1")

        stack = tmp_stack
        # 補齊結果如下
        # print stack
        # ['K', '4', '(', 'O', '1', 'N', '1', '(', 'S', '1', 'O', '3', ')', '2', ')', '2']

        # 第三步,開始遍歷,進行計算,每次遇到一個“)”都往回找“(”,把括號外的數字乘進去,並組合元素和數字
        stack2 = list()
        i = 0
        l = len(stack)
        while i < l:
            if stack[i].isalpha():
                stack2.append([stack[i],stack[i+1]])
                i += 2
            elif stack[i] == '(':
                stack2.append(stack[i])
                i += 1
            elif stack[i] == ')':
                num = int(stack[i+1])
                tmp = list()
                c = stack2.pop()
                while i > 0 and c != '(':
                    c1 = [c[0], str(int(c[1]) * num)]
                    tmp.append(c1)
                    c = stack2.pop()
                stack2.extend(tmp)
                i += 2

        # print stack2
        # [['K', '4'], ['S', '4'], ['O', '12'], ['N', '2'], ['O', '2']]

        # 第四步,計算基本完成,將結果中重複元素合併,
        result_dict = {}
        for i in stack2:
            if result_dict.has_key(i[0]):
                count = result_dict[i[0]] + int(i[1])
                result_dict[i[0]] = count
            else:
                result_dict[i[0]] = int(i[1])
        result = ""
        sor = sorted(result_dict)
        for key in sor:
            if result_dict[key] == 1:
                result += key
            else:
                result += str(key)+str(result_dict[key])

        print result
        # K4N2O14S4
        return result

# a = Solution()
# a.countOfAtoms("K4(ON(SO3)2)2")

 時間複雜度: O(n)