LeetCode 每日一题 2024/12/30-2024/1/5

记录了初步解题思路 以及本地实现代码;并不一定为最优 也希望大家能一起探讨 一起进步




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



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值