python算法之旅(3)- Integer to Roman

原問題鏈接https://leetcode.com/problems/integer-to-roman/description/

不關心問題的解決,只關心不同的解決問題的思路,所有的思路均在代碼中註釋,大家邊看代碼邊看思路,

下面附上解決方案,具體需要注意的地方都在代碼中註釋很清楚,轉載請註明出處,或在下方回覆

#_*_ coding:utf-8 _*_

'''
補充知識:請自行百度羅馬數字的表示方法,或者參考我的solution2 和solution3通過代碼去理解
'''
# 三次運行結果
# 4.90%  234ms
# 19.59% 182ms
# 46.60% 161ms
class Solution1(object):
    def intToRoman(self, num):
        """
        :type num: int
        :rtype: str
        """
        roman={
            '1':'I',
            '10':'X',
            '100':'C',
            '1000':'M',
            '5':'V',
            '50':'L',
            '500':'D'
        }
        thousand=num/1000
        hundred=(num/100)%10
        ten=(num/10)%10
        single=num%10
        result='' # 拼接結果
        for i in range(thousand):
            result+=roman['1000']

        if hundred == 9:
            result+=roman['100']+roman['1000']
        else:
            if hundred>=5:
                result+=roman['500']
                hundred-=5
            if hundred==4:
                result += roman['100']+roman['500']
            else:
                for i in range(hundred):
                    result+=roman['100']

        if ten == 9:
            result+=roman['10']+roman['100']
        else:
            if ten>=5:
                result+=roman['50']
                ten-=5
            if ten==4:
                result += roman['10'] + roman['50']
            else:
               for i in range(ten):
                result+=roman['10']
        if single == 9:
            result+=roman['1']+roman['10']
        else:
            if single>=5:
                result+=roman['5']
                single-=5
            if single==4:
                result += roman['1'] + roman['5']
            else:
                for i in range(single):
                    result+=roman['1']
        return result
'''
在solution1的基礎上進行簡化和統一處理,增加了程序的可讀性和邏輯性,
將羅馬數字的表示方法很清楚地封裝到一個函數中
說真的,並沒有對算法進行優化,所以運行時間上和solution1沒有太大差別,甚至可能慢一點
畢竟字典定義成了公有變量,並且str_1,str_5,str_10都需要動態計算,而在1裏面是直接給定的
因此會導致比1中略微慢一點
'''
class Solution2(object):
    roman = {'1': 'I', '10': 'X', '100': 'C', '1000': 'M', '5': 'V', '50': 'L', '500': 'D'}
    # num  表示該位的數字
    # rate 表示進率
    def convert(self,num,rate):
        tmp_result=''
        # 在使用int 轉str 的時候,後面的一定要括起來作爲一個整體
        str_1 ="%d" % (1*rate)
        str_5 = "%d" % (5 * rate)
        str_10 = "%d" % (10 * rate)
        if num == 9:
            tmp_result+=self.roman[str_1]+self.roman[str_10]
        else:
            if num>=5:
                tmp_result+=self.roman[str_5]
                num-=5
            if num==4:
                tmp_result += self.roman[str_1]+self.roman[str_5]
            else:
                for i in range(num):
                    tmp_result+=self.roman[str_1]
        return tmp_result
    def intToRoman(self, num):
        """
        :type num: int
        :rtype: str
        """

        thousand=num/1000
        hundred=(num/100)%10
        ten=(num/10)%10
        single=num%10
        result=self.convert(thousand,1000)+self.convert(hundred,100)+self.convert(ten,10)+self.convert(single,1) # 拼接結果

        return result

'''
這第三種就比較粗暴了,但應該也是不可能有更高效的了
(真的,我感覺剩下的只是一些誤差或者是算術部分的小差別了,真正的思路上這個應該是最高效的了)
因爲羅馬數字只能表示4位數,所以列出每一位的所有10種情況,
然後直接使用列表定位就好了
'''
# 54.82% 157ms
# 65.09% 151ms
# 84.99% 126ms
# 90.08% 118ms
class Solution3(object):
    def intToRoman(self, num):
        """
        :type num: int
        :rtype: str
        """
        thousand_all = ["", "M", "MM", "MMM"]
        hundred_all = ["", "C", "CC", "CCC", "CD", "D", "DC", "DCC", "DCCC", "CM"]
        ten_all = ["", "X", "XX", "XXX", "XL", "L", "LX", "LXX", "LXXX", "XC"]
        single_all =["", "I", "II", "III", "IV", "V", "VI", "VII", "VIII", "IX"]
        thousand = num / 1000
        hundred = (num / 100) % 10
        ten = (num / 10) % 10
        single = num % 10
        return thousand_all[thousand]+hundred_all[hundred]+ten_all[ten]+single_all[single]

so1=Solution1()
print so1.intToRoman(3999)

so2=Solution2()
print so2.intToRoman(3999)

so3=Solution3()
print so3.intToRoman(3999)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章