# 前言

## 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 = []
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]
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]
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}'
06-12 90
05-02 151

06-11 110
07-28 44
08-02 51
03-20 500
12-03 1061
05-28 175
05-25 135
04-19 2369