• LeetCode 每日一题 2023/9/18-2023/9/24


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




    9/18 337. 打家劫舍 III

    对于一节node有两种情况 偷 或者 不偷
    lrrob函数返回 偷这个node 和 不偷这个node 能够得到的最佳情况
    如果这个点为空 那么 偷不偷的情况都是0
    获得改点左右子节点的情况 lrob,lnot(偷/不偷左节点) rrob,rnot(偷/不偷右节点)
    如果要偷 那么对于就不能偷他的左右子节点 得到 val+lnot+rnot
    如果不偷 那么对于左右子节点可以选择偷或不偷 选最大值 max(lrob,lnot)+max(rrob,rnot)

    class TreeNode(object):
        def __init__(self, x):
            self.val = x
            self.left = None
            self.right = None
    
    def rob(root):
        """
        :type root: TreeNode
        :rtype: int
        """
        def lrrob(node):
            if not node:
                return 0,0
            lrob,lnot = lrrob(node.left)
            rrob,rnot = lrrob(node.right)
            
            return node.val+lnot+rnot, max(lrob,lnot)+max(rrob,rnot)
        
        return max(lrrob(root))
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    9/19 2560. 打家劫舍 IV

    二分 偷窃能力必定在min(nums),max(nums)的区间内
    对与偷窃能力m
    遍历所有房子
    只关心偷或者不偷 所以遇到能偷的就偷 统计能偷的数量

    def minCapability(nums, k):
        """
        :type nums: List[int]
        :type k: int
        :rtype: int
        """
        l,r = min(nums),max(nums)
        while l<r:
            m = (l+r)//2
            pre,take=0,0
            for num in nums:
                if pre:
                    pre=0
                    continue
                if num<=m:
                    take+=1
                    pre=1
                if take>=k:
                    break
            if take>=k:
                r = m
            else:
                l = m+1
        return l
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26

    9/20 LCP 06. 拿硬币

    减少次数 每次尽量拿两枚
    对于一对n个硬币 需要拿取(n+1)//2次

    
    def minCount(coins):
        """
        :type coins: List[int]
        :rtype: int
        """
        ans = 0
        for c in coins:
            ans +=(c+1)//2
        return ans
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    9/21 2603. 收集树中金币

    如果一个节点度数为1 即只有一个邻居 可以称作叶子节点
    如果一个叶子节点没有金币 则这叶子节点可以直接去除
    直至所有叶子节点都包含金币
    由于可以直接收集距离为2以内的金币 所以我们只需要访问叶子节点的父节点的父节点
    将所有叶子节点去除 再将新叶子节点去除 剩余的是我们必须要访问的节点
    因为要回到出发点 所以每条边必定走两次

    def collectTheCoins(coins, edges):
        """
        :type coins: List[int]
        :type edges: List[List[int]]
        :rtype: int
        """
        n= len(coins)
        g = [[] for _ in range(n)]
        for x,y in edges:
            g[x].append(y)
            g[y].append(x)
        deg = list(map(len,g))
        
        eg = n-1
        l = []
        for i,(d,c) in enumerate(zip(deg,coins)):
            if d==1 and c==0:
                l.append(i)
        while l:
            eg-=1
            for y in g[l.pop()]:
                deg[y]-=1
                if deg[y]==1 and coins[y]==0:
                    l.append(y)
                    
        for i,(d,c) in enumerate(zip(deg,coins)):
            if d==1 and c:
                l.append(i)
        eg -= len(l)
        for x in l:
            for y in g[x]:
                deg[y]-=1
                if deg[y]==1:
                    eg-=1
        return max(eg*2,0)
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37

    9/22 2591. 将钱分给最多的儿童

    如果钱少于儿童 则没有分配方案
    先将每个儿童分配1元 然后查看还能分配出几个7元
    处理特殊情况

    def distMoney(money, children):
        """
        :type money: int
        :type children: int
        :rtype: int
        """
        if money<children:
            return -1
        left = money-children
        ans = min(children,left//7)
        if ans+1==children and ans*8+4==money:
            ans-=1
        if ans==children and ans*8!=money:
            ans-=1
        return ans
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    9/23 1993. 树上的操作

    locked[i]用来记录节点i被哪一个用户上锁
    parent[i]记录节点i的父节点
    children[i] 记录节点i的子节点
    dfs判断子孙节点是否由上锁的

    class LockingTree(object):
    
        def __init__(self, parent):
            """
            :type parent: List[int]
            """
            n=len(parent)
            self.locked = [-1]*n
            self.parent = parent
            self.children = [[] for _ in range(n)]
            for s,p in enumerate(parent[1:],1):
                self.children[p].append(s)
    
    
        def lock(self, num, user):
            """
            :type num: int
            :type user: int
            :rtype: bool
            """
            if self.locked[num]==-1:
                self.locked[num]=user
                return True
            return False
    
    
        def unlock(self, num, user):
            """
            :type num: int
            :type user: int
            :rtype: bool
            """
            if self.locked[num]==user:
                self.locked[num]=-1
                return True
            return False
    
    
        def upgrade(self, num, user):
            """
            :type num: int
            :type user: int
            :rtype: bool
            """
            global find
            def dfs(x):
                global find
                for c in self.children[x]:
                    if self.locked[c]!=-1:
                        self.locked[c]=-1
                        find = True
                    dfs(c)
            x=num
            while x!=-1:
                if self.locked[x]!=-1:
                    return False
                x = self.parent[x]
            
            find=False
            dfs(num)
            if not find:
                return False
            self.locked[num]=user
            return True
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66

    9/24 146. LRU 缓存

    fr存储最近是用过的key
    kw存储key对应的value

    from collections import defaultdict
    class LRUCache:
    
        def __init__(self, capacity: int):
            self.cp = capacity
            self.kw = defaultdict(int)
            self.fr = []
            
    
        def get(self, key: int) -> int:
            if key in self.kw:
                self.fr.remove(key)
                self.fr.insert(0,key)
                return self.kw[key]
            else:
                return -1
    
        def put(self, key: int, value: int) -> None:
            if key in self.kw or len(self.kw)<self.cp:
                self.kw[key] = value
                if key in self.fr:
                    self.fr.remove(key)
                self.fr.insert(0,key)
            else:
                k = self.fr[-1]
                print(k,key)
                self.kw.pop(k)
                self.kw[key] = value
                self.fr.remove(k)
                self.fr.insert(0,key)
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32

  • 相关阅读:
    万字手撕AVL树 | 上百行的旋转你真的会了吗?【超用心超详细图文解释 | 一篇学会AVL】
    linux Make 工具 Makefile变量
    解决wave.Error: unknown format: 3
    机器学习的安全及隐私保护研究
    人人开源搭建后台管理系统 & 逆向工程生成CRUD代码
    分布式系统中的一些问题
    瑞_Redis_短信登录(二)
    vue3 + ts: layout布局
    Android HIDL 介绍学习之客户端调用
    浮点数类型讲解
  • 原文地址:https://blog.csdn.net/zkt286468541/article/details/133129678