LeetCode 解体代码Python 11-20

这篇博客探讨了多种算法问题的解决方案,包括盛最多水的容器、整数与罗马数字转换、最长公共前缀、三数之和、最接近的三数之和以及有效的括号验证。通过代码实现,展示了如何运用数学和字符串操作来解决这些经典计算机科学问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

目录

11盛最多水的容器

12整数转罗马数字

13罗马数字转整数

14最长公共前缀

15三数之和

16最接近的三数之和

17电话号码的字母组合

18四数之和

19删除链表的倒数第N个结点

20有效的括号

 


11盛最多水的容器

class Solution:
    def maxArea(self, height: List[int]) -> int:
        s, e= 0, len(height)-1
        v = (e-s)*min(height[s],height[e])
        while e-s>1:
            # 挑短边往前走
            if height[s] < height[e]:
                s +=1
            else:
                e -=1
            v = max((e-s)*min(height[s],height[e]), v)
        return v

12整数转罗马数字

class Solution:
    def intToRoman(self, num: int) -> str:
        res = ''
        for f in [1000, 100, 10, 1]:
            res = res + self.unit(f, num//f)
            num -= num//f*f
        return res

    def unit(self, loc=1, val=0) -> str:
        dic = {1:['I','V','X'], 10:['X','L','C'], 100:['C','D','M'], 1000:['M','?','?']}
        cur = dic[loc] # 确认在第几位
        # 按位遍历
        if val == 0:   return ''
        elif val == 4: return cur[0]+cur[1]
        elif val == 5: return cur[1]
        elif val == 9: return cur[0]+cur[2]

        if val>5: return cur[1]+cur[0]*(val-5)
        else:     return cur[0]*val

13罗马数字转整数

class Solution:
    def romanToInt(self, s: str) -> int:
        res = 0
        for f in [1000, 100, 10, 1]:
            val, num = self.unit(f, s)
            res += val*f
            s = s[num:]
        return res

    
    def unit(self, loc=1, ss=''):
        dic = {1:['I','V','X'], 10:['X','L','C'], 100:['C','D','M'], 1000:['M','#','#']}
        cur = dic[loc]
        # 向前处理:按位翻译,十位上的情况分为:11-X+I, 41-XL+I, 51-LI, 71-LXX+I, 91-XM+I——>开头都是X、L
        # 还要排除特殊情况会出现XL:9-IX
        if len(ss)>0 and ss[0] in cur[:-1]:
            # X开头的3种情况
            if   ss[:2] == ''+cur[0]+cur[2]: return 9,2 # 匹配XM
            elif ss[:2] == ''+cur[0]+cur[1]: return 4,2 # 匹配XL
            elif ss[0]  == cur[0]: # 匹配X*
                count =0
                while count<len(ss) and ss[count]==cur[0]: count+=1
                return count, count
            elif ss[0] == cur[1]: # 匹配V/VX*
                count =0
                while count+1<len(ss) and ss[1+count]==cur[0]: count+=1
                return 5+count, 1+count
        return 0,0

看到一个超简洁代码:

class Solution:
    def romanToInt(self, s: str) -> int:
        d = {'I':1, 'IV':3, 'V':5, 'IX':8, 'X':10, 'XL':30, 'L':50, 'XC':80, 'C':100, 'CD':300, 'D':500, 'CM':800, 'M':1000}
        return sum(d.get(s[max(i-1, 0):i+1], d[n]) for i, n in enumerate(s))

14最长公共前缀

class Solution:
    def longestCommonPrefix(self, strs: List[str]) -> str:
        if len(strs) == 0: return ""
        # 排序
        sorteds = sorted(strs)
        # 对比第一个和最后一个
        end =0
        while end < len(sorteds[0]) and end < len(sorteds[-1]):
            if sorteds[0][end] != sorteds[-1][end]: break
            end +=1
        return sorteds[0][:end]

15三数之和

class Solution:
    def threeSum(self, nums: List[int]) -> List[List[int]]:
        res = []
        oldnum=10**5+1 # 设定一个超出范围的值
        nums = sorted(nums)
        while len(nums)>=3:
            if sum(nums[:3]) > 0: break # 最小的三个数之和都>0,放弃吧
            elif nums[0]==oldnum: # 重复值不遍历
                nums = nums[1:]
                continue
            s,e=1,len(nums)-1 # 双指针
            while s<e:
                if nums[0]+nums[s]+nums[e]==0:
                    if [nums[0],nums[s],nums[e]] not in res: # 去除重复值
                        res.append([nums[0],nums[s],nums[e]])
                    s,e=s+1,e-1 # 改成while语句避免重复,没有任何优化效果(奇怪)
                elif nums[0]+nums[s]+nums[e]>0: e-=1
                else: s+=1
            oldnum = nums[0] # 这句话可以提高1000ms
            nums = nums[1:]
        return res

16最接近的三数之和

思路同15

class Solution:
    def threeSumClosest(self, nums: List[int], target: int) -> int:
        nums = sorted(nums)
        res = sum(nums[:3])
        while len(nums)>2:
            s,e = 1, len(nums)-1
            while s<e:
                summ = nums[0]+nums[s]+nums[e]
                if abs(summ-target) < abs(res-target): res = summ
                if summ == target: return target
                elif summ > target: e-=1
                else: s+=1
            nums = nums[1:]
            if res > target and sum(nums[:3]) > target: break #最小的三个数之和都比目标大,停止吧
        return res

17电话号码的字母组合

class Solution:
    def letterCombinations(self, digits: str) -> List[str]:
        if len(digits) == 0: return []
        self.res =[]
        self.backtrack('', digits)
        return self.res

    def backtrack(self, s:str, digits: str):
        if len(digits) == 0: self.res.append(s)
        else:
            dic = {"2":"abc","3":"def",'4':"ghi",'5':"jkl",'6':"mno",'7':"pqrs",'8':"tuv",'9':"wxyz"}
            for l in dic[digits[0]]:
                self.backtrack(s+l, digits[1:])

18四数之和

19删除链表的倒数第N个结点

20有效的括号

class Solution:
    def isValid(self, s: str) -> bool:
        dic = {'(':')', '{':'}', '[':']'}
        q = []
        for ss in s:
            if ss in dic.keys(): q.append(ss)
            if ss in dic.values():
                if len(q)>0 and ss == dic[q[-1]]: q = q[:-1] # 错误:"]"
                else: return False
        if len(q)>0: return False # 错误:"["
        return True

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值