leetcode刷题记录631-640 python版

前言

继续leetcode刷题生涯
这里记录的都是笔者觉得有点意思的做法
参考了好几位大佬的题解,感谢各位大佬

632. 最小区间

import heapq
class Solution:
    def smallestRange(self, nums: List[List[int]]) -> List[int]:
        n = len(nums)
        elem_id_index = [(elem[0], id, 0) for id, elem in enumerate(nums)]
        heapq.heapify(elem_id_index)
        maxval, minval = 1e5, -1e5
        currmaxval = max(elem_id_index)[0]
        while True:
            currminval, id, index = heapq.heappop(elem_id_index)
            if currmaxval - currminval < maxval - minval:
                maxval = currmaxval
                minval = currminval
            if index < len(nums[id]) - 1:
                val = nums[id][index+1]
                currmaxval = max(currmaxval, val)
                heapq.heappush(elem_id_index, (val, id, index+1))
            else:
                break
        return [minval, maxval]

633. 平方数之和

class Solution:
    def judgeSquareSum(self, c: int) -> bool:
        l,r = 0, int(math.sqrt(c))
        while l <= r:
            if c==l*l+r*r:
                return True
            elif l*l+r*r>c:
                r=r-1
            else:
                l=l+1

636. 函数的独占时间

class Solution:
    def exclusiveTime(self, n: int, logs: List[str]) -> List[int]:
        res = [0 for _ in range(n)]
        stack = []
        time_s = []
        for log in logs:
            ID, act, time = log.split(':')
            if(act == 'start'):
                stack.append(int(ID))
                time_s.append(int(time))
            if(act == 'end'):
                interval = int(time) - time_s.pop() + 1
                res[stack.pop()] += interval
                if len(stack) != 0:
                    res[stack[-1]] -= interval
        return res

637. 二叉树的层平均值

class Solution:
    def averageOfLevels(self, root: TreeNode) -> List[float]:
        if not root: return []
        import collections
        res = collections.defaultdict(list)
        def dfs(root, depth):
            if not root: return
            res[depth] += [root.val]
            dfs(root.left, depth+1)
            dfs(root.right, depth+1)
        dfs(root, 0)
        return [sum(layer) / len(layer) for layer in res.values()]

638. 大礼包

# 分支限界法
class Solution:
    def shoppingOffers(self, price: List[int], special: List[List[int]], needs: List[int]) -> int:
        # 单独购买物品时的价格
        self.price = sum([p * n for p, n in zip(price, needs)])
        # 购买大礼包时比单独购买便宜的价格
        for sp in special:
            sp.append(sp[-1] - sum([p * n for p, n in zip(price, sp[:-1])]))
        # 优先搜索更便宜的大礼包
        special.sort(key=lambda x: x[-1])
        current = 0
        def find(special, needs, current):
            for sp in special:
                if flag(needs, sp):
                    sub(needs, sp)
                    current += sp[-2]
                    # 根据上界剪枝
                    if current < self.price:
                        find(special, needs, current)
                    current -= sp[-2]
                    add(needs, sp)
            t = sum([p * n for p, n in zip(price, needs)])
            # 更新上界
            self.price = min(self.price, current + t)
        def flag(needs, sp):
            for i in range(len(needs)):
                if needs[i] < sp[i]:
                    return False
            return True
        def sub(needs, sp):
            for i in range(len(needs)):
                needs[i] -= sp[i]
        def add(needs, sp):
            for i in range(len(needs)):
                needs[i] += sp[i]
        find(special, needs, current)
        return self.price

639. 解码方法 2

class Solution:
    def numDecodings(self, s: str) -> int:
        M=1000000007 
        #dp初始化,dp[1]为s中第一个字符的可能性个数
        dp=[0]*(len(s)+1)
        dp[0]=1
        if s[0]=='*': dp[1]=9
        elif s[0]=='0': dp[1]=0
        else:dp[1]=1
        for i in range(1,len(s)):
            #当前字符s[i]看做一个一位数字
            if s[i]=='*': dp[i+1]+=dp[i]*9
            elif s[i]!='0': dp[i+1]+=dp[i]
            # s[i-1]+s[i]看做一个两位数字,四种情况: *n,**,nn,n*
            if s[i-1]=='*':
                if s[i]!='*': 
                    dp[i+1]+=dp[i-1]*(2 if int(s[i])<=6 else 1)
                else:
                    dp[i+1]+=dp[i-1]*15
            else:
                if s[i]!='*':
                    num=int(s[i-1]+s[i])
                    dp[i+1]+=dp[i-1]*(1 if 10<=num<=26 else 0)
                else:
                    if s[i-1]=='1': count=9
                    elif s[i-1]=='2': count=6
                    else: count=0
                    dp[i+1]+=dp[i-1]* count
            dp[i+1]%=M
        return dp[-1]

640. 求解方程

class Solution:
    def solveEquation(self, equation: str) -> str:
        l, r = equation.split('=')
        def parse(expression: str) -> (int, int):
            w = 0
            b = 0
            expression = expression.replace('-', '+-')
            if expression.startswith('+'):
                expression = expression[1:]
            items = expression.split('+')
            for i in items:
                if i.endswith('x'):
                    s = i[:-1]
                    if s == '':
                        w += 1
                    elif s == '-':
                        w -= 1
                    else:
                        w += int(s)
                else:
                    b += int(i)
            return w, b

        lw, lb = parse(l)
        rw, rb = parse(r)
        fw = lw - rw
        fb = rb - lb
        if fw == 0:
            if fb == 0:
                return 'Infinite solutions'
            else:
                return 'No solution'
        return f'x={fb // fw}'
©️2020 CSDN 皮肤主题: 技术黑板 设计师:CSDN官方博客 返回首页