Leetcode算法做题记录(二)

题目7

题目描述

解法1

【算法思路】:
① 使用列表,将输入数字的每一位从个位起依次存入列表;
② 对列表中的0元素进行处理,然后将列表的元素变为数字输出;
③ 根据条件返回对应的翻转数字;
④ 算法复杂度为O(n),较高。
【代码】:

class Solution:
    def reverse(self, x):
        """
        type x: int
        rtype : int
        """
        nums = []
        if x == 0:    # 0的翻转为0
            return 0
        x_ = abs(x)   # 无论正负都先按照正数处理
        while x_ > 0: # 将输入整数的每一位存入到列表里
            #nums[i] = x_ % 10 列表为空时不能赋值
            nums.append(x_%10)
            x_ = x_ // 10
        for i in range(len(nums)):# 对0元素进行处理
            if nums[0] != 0:
                break
            else:
                nums.pop(0)   
        if  eval(''.join(str(t) for t in nums)) > math.pow(2,31):# 判断翻转后的数字是否越界
            return 0  
        if x > 0: # 根据正负数返回不同的数值
            return(eval(''.join(str(t) for t in nums)))
        else:
            return(eval("-"+(''.join(str(t) for t in nums))))

【测试截图】:
测试截图

解法2

【算法思路】:
① 将整数先转化为字符;
② 对字符使用切片操作进行翻转;
③ 再将字符串转化为整数后根据条件输出翻转的数;
④ 用了切片操作,其算法复杂度为O(n)
【代码】:

class Solution:
    def reverse(self, x):
        """
        type x: int
        rtype : int
        """
        if x >= 0:
            reversed_x = int(str(x)[::-1])
        else:
            reversed_x = -int(str(x)[:0:-1])  # 不加负号在本地编译器上可以通过,在LeetCode上没有过
        if  -math.pow(2, 31) < reversed_x < math.pow(2, 31) - 1:
            return reversed_x
        else:
            return 0

【测试截图】:
测试截图

题目66

解法1

【算法思路】:
① 分情况进行处理:最后一位数字不是9,最后一位数字是9且9的个数和数字位数相等,最后一位是9但9 的个数和数字位数不相等;
② 如果最后一位不是9,那么直接在最后一位加一后输出;
③ 如果整数全是9,如9, 99, 999, 9999…那么将第一位赋值为1,后面全为0,在 加一个零;
④ 如果整数不全是9,在从后往前第一个不是9的数字上加一,后面的数字全部另为0
【代码】:

class Solution:
    def plusOne(self, digits: List[int]) -> List[int]:
        """
        type digits: List[int]
        rtype:       List[int]
        """
        num = 0
        if digits[-1] != 9:  # 如果最后一位不是9,那么直接在最后一位加一后输出
            digits[-1] += 1
            return digits
        for i in range(len(digits)):# 如果整数带9,首先从最后一位开始计算9的个数num
            if digits[-1-i] == 9:
                num += 1
            else:
                break
        if num == len(digits):   # 如果整数全是9,如9,99,999,9999......那么将第一位赋值为1,后面全为0,在                                     加一个零
            digits[0] = 1
            for i in range(len(digits)-1):
                digits[-1-i] = 0
            digits.append(0)
        else:                    # 否则的话在从后往前第一个不是9的数字上加一,后面的数字全部另为0
            digits[-1-num] += 1
            for i in range(num):
                digits[-1-i] = 0
        return digits 

【测试截图】:
测试截图

解法2

【算法思路】:更聪明、优雅、简洁的做法
① 将解法1中的情况1和3合并到一起,并且使用取模的做法,通过有进位的数字判断9,无需先行计算9的个数,更简单。
② 算法过程为:从最后一位开始依次往前遍历,依次判断每一位加1之后是否有进位,直到没有进位时,返回数字加1;否则首位变1,末位加0;
③ 算法复杂度:O(n)。
【代码】:

class Solution:
    def plusOne(self, digits: List[int]) -> List[int]:
        """
        type digits: List[int]
        rtype:       List[int]
        """
        for i in range(len(digits)-1, -1, -1):# 从最后一位开始依次往前遍历
            digits[i] += 1                    # 依次判断每一位加1之后是否有进位
            digits[i] = digits[i] % 10        # 直到没有进位时,返回数字加1
            if digits[i] != 0:                # 情况:187,1899......
                return digits
        digits[0] = 1                         # 情况:9, 99, 999......首位变1,末尾加0
        digits.append(0)                     
        return digits

【测试截图】:
在这里插入图片描述

题目13

解法1

题目描述
【算法思路】:
① 将基本字符存入字典中;
② 从后往前遍历输入的字符串,从最后一个字符开始前后两两比较,看是否为特殊情况(右边的数大于左边的数);
③ 为了保证两两判断的可行性,对遍历的字符下标做规定,以保证不会产生索引越界的情况,即遍历的索引不能大于len(s)-1,这样才能保证最多取到s[0];
④ 对于s[1]s[2]是特殊情况时,单独对s[0]做处理。
【代码】:

class Solution:
    def romanToInt(self, s: str) -> int:
        """
        type s: str
        rtype: int
        """
        sum = 0
        i = 0
        dict = {'I':1, 'V':5, 'X':10, 'L':50, 'C':100, 'D':500, 'M':1000} # 字典定义基本字符
        while i < len(s):   # 从后往前遍历字符串
            if i < (len(s)-1):  # 保证始终能进行前后比较,不能出现s[-len(s)-1]的情况,即最多只能到s[0]
                if dict[s[-1-i]] > dict[s[-1-i-1]]:
                    sum += (dict[s[-1-i]] - dict[s[-1-i-1]])
                    i += 2
                    continue
                else:
                    sum += dict[s[-1-i]]
                    i += 1
                    continue
            else: # s[1]s[2]是特殊情况,即存在s[0]时,将s[0]加上去
                sum += dict[s[0]]
                i += 1
                continue
        return sum

【测试截图】:
测试截图

解法2:透过现象看本质

【算法思路】:
① 当罗马数字中小数字在大数字左边时,大数字-小数字(eg. IV = 4),否则,大数字+小数字(eg. VI = 6);
② 对每一位字符与其下一位字符进行判断,判断到s[-2]结束;
③ 最后加上s[-1]。
【注】罗马数字的正确性保证了不会出现题目外其他的小数字在大数字左边的情况以及连续两组(3个罗马数字)小数字在大数字左边的情况。
【代码】:

class Solution:
    def romanToInt(self, s: str) -> int:
        """
        type s: str
        rtype: int
        """
        sum = 0
        dict = {'I':1, 'V':5, 'X':10, 'L':50, 'C':100, 'D':500, 'M':1000} # 字典定义基本字符
        for i in range(len(s)-1):
            if dict[s[i]] < dict[s[i+1]]:    # 小数字在大数字左边
                sum -= dict[s[i]]
            else:                            # 小数字在大数字右边
                sum += dict[s[i]]
        sum += dict[s[-1]]
        return sum

【测试截图】:
在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值