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)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值