记录了初步解题思路 以及本地实现代码;并不一定为最优 也希望大家能一起探讨 一起进步
目录
12/30 1367. 二叉树中的链表
遍历二叉树每个节点
class ListNode(object):
def __init__(self, val=0, next=None):
self.val = val
self.next = next
# Definition for a binary tree node.
class TreeNode(object):
def __init__(self, val=0, left=None, right=None):
self.val = val
self.left = left
self.right = right
def isSubPath(head, root):
"""
:type head: Optional[ListNode]
:type root: Optional[TreeNode]
:rtype: bool
"""
def check(tr,li):
if li==None:
return True
if tr==None:
return False
return li.val==tr.val and (check(tr.left,li.next) or check(tr.right,li.next))
l=[root]
while l:
tmp = []
for node in l:
if check(node,head):
return True
if node.left:
tmp.append(node.left)
if node.right:
tmp.append(node.right)
l=tmp
return False
12/31 3219. 切蛋糕的最小总开销 II
如果竖着切了x刀 那么每条水平线上横着切的开销总和为(x+1)*h[i]
同理横着切了y刀 那么每条垂直线上总和为(y+1)*v[j]
综上切了一刀 会导致另一维度上的每条线上都会增加一次消耗
为了减少总开销 减少大开销的增加
将没到开销从大到小排序 优先挑选开销大的切
def minimumCost(m, n, horizontalCut, verticalCut):
"""
:type m: int
:type n: int
:type horizontalCut: List[int]
:type verticalCut: List[int]
:rtype: int
"""
x,y=0,0
ans = 0
l = [(horizontalCut[i],0) for i in range(m-1)]+[(verticalCut[j],1) for j in range(n-1)]
l.sort(reverse=True)
for v,tag in l:
if tag==0:
y+=1
ans+=(x+1)*v
else:
x+=1
ans+=(y+1)*v
return ans
1/1 3280. 将日期转换为二进制表示
分别取年月日转换
def convertDateToBinary(date):
"""
:type date: str
:rtype: str
"""
l=date.split("-")
return "".join([bin(int(x))[2:] for x in l])
1/2 729. 我的日程安排表 I
线段树简化版
初始化区间每个未预订的点为0
预定的时间标记为1
每次查询区间是否包含被标记的1
node[idx]记录节点idx是否包含1
lazy[idx]记录 该节点内都被标记为1
class MyCalendar(object):
def __init__(self):
self.node = set()
self.lazy = set()
def query(self,start,end,l,r,idx):
if start>r or end<l:
return False
if idx in self.lazy:
return True
if start<=l and r<=end:
return idx in self.node
mid = (l+r)>>1
return self.query(start,end,l,mid,2*idx) or self.query(start,end,mid+1,r,2*idx+1)
def update(self,start,end,l,r,idx):
if start>r or end<l:
return
if start<=l and r<=end:
self.node.add(idx)
self.lazy.add(idx)
else:
mid = (l+r)>>1
self.update(start,end,l,mid,2*idx)
self.update(start,end,mid+1,r,2*idx+1)
self.node.add(idx)
if 2*idx in self.lazy and 2*idx+1 in self.lazy:
self.lazy.add(idx)
def book(self, start, end):
"""
:type start: int
:type end: int
:rtype: bool
"""
if self.query(start,end-1,0,10**9,1):
return False
self.update(start,end-1,0,10**9,1)
return True
1/3 731. 我的日程安排表 II
线段树 动态开点
val记录各节点已有次数
lazy懒标记 记录该节点内子节点已有次数未下发
class MyCalendarTwo(object):
def __init__(self):
self.val = {}
self.lazy = {}
def update(self,start,end,l,r,idx,val):
if start>r or end<l:
return
if start<=l and r<=end:
self.val[idx] = self.val.get(idx,0)+val
self.lazy[idx] = self.lazy.get(idx,0)+val
return
mid = (l+r)>>1
self.update(start,end,l,mid,2*idx,val)
self.update(start,end,mid+1,r,2*idx+1,val)
v = max(self.val.get(2*idx,0),self.val.get(2*idx+1,0))
self.val[idx] = self.lazy.get(idx,0)+v
def book(self, start, end):
"""
:type start: int
:type end: int
:rtype: bool
"""
self.update(start,end-1,0,10**9,1,1)
if self.val.get(1,0)>2:
self.update(start,end-1,0,10**9,1,-1)
return False
return True
1/4 732. 我的日程安排表 III
将每个日程看作一条线段 求每个时间点上最多有几个日程
1.差分数组
日程起始处+1 日程结束处-1 从头遍历 每经过一个时间点
求当前拥有日程的最大值
2.线段树
动态开点+懒标记模板
class MyCalendarThree1(object):
def __init__(self):
self.m = {}
def book(self, start, end):
"""
:type start: int
:type end: int
:rtype: int
"""
self.m[start] = self.m.get(start,0)+1
self.m[end] = self.m.get(end,0)-1
l = sorted(self.m.keys())
cur = 0
ans = 0
for t in l:
cur += self.m[t]
ans = max(ans,cur)
return ans
####################################################
class Node:
def __init__(self,l,r):
self.left = None
self.right = None
self.l = l
self.r = r
self.mid = (l+r)>>1
self.v = 0
self.add = 0
class SegmentTree:
def __init__(self):
self.root = Node(1,int(1e9+1))
def modify(self,l,r,v,node=None):
if l>r:
return
if not node:
node = self.root
if node.l>=l and node.r<=r:
node.v +=v
node.add +=v
return
self.pushdown(node)
if l<=node.mid:
self.modify(l,r,v,node.left)
if r>node.mid:
self.modify(l,r,v,node.right)
self.pushup(node)
def pushdown(self,node):
if not node.left :
node.left = Node(node.l,node.mid)
if not node.right:
node.right = Node(node.mid+1,node.r)
if node.add:
node.left.v += node.add
node.right.v += node.add
node.left.add += node.add
node.right.add += node.add
node.add = 0
def pushup(self,node):
node.v = max(node.left.v,node.right.v)
def query(self,l,r,node=None):
if l>r:
return 0
if not node:
node = self.root
if node.l>=l and node.r <=r:
return node.v
self.pushdown(node)
v = 0
if l<=node.mid:
v = max(v,self.query(l,r,node.left))
if r>=node.mid:
v = max(v,self.query(l,r,node.right))
return v
class MyCalendarThree2(object):
def __init__(self):
self.tr = SegmentTree()
def book(self, start, end):
"""
:type start: int
:type end: int
:rtype: int
"""
self.tr.modify(start+1,end,1)
return self.tr.query(1,int(1e9+1))
1/5 2241. 设计一个 ATM 机器
每次取钱从大到小考虑
class ATM(object):
def __init__(self):
self.value = [20,50,100,200,500]
self.cnt=[0]*5
def deposit(self, banknotesCount):
"""
:type banknotesCount: List[int]
:rtype: None
"""
for i in range(5):
self.cnt[i]+=banknotesCount[i]
def withdraw(self, amount):
"""
:type amount: int
:rtype: List[int]
"""
ans=[0]*5
for i in range(4,-1,-1):
v=self.value[i]
ans[i]=min(self.cnt[i],amount//v)
amount-=v*ans[i]
if amount>0:
ans=[-1]
else:
for i in range(5):
self.cnt[i]-=ans[i]
return ans