• LeetCode 每日一题 2022/11/21-2022/11/27


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




    11/21 808. 分汤

    可以将25ml看作1份 四种情况分别为
    A 4 B 0
    A 3 B 1
    A 2 B 2
    A 1 B 3
    开始时 A,B拥有的份数一样
    当n过大时 A被取完的概率接近于1 误差小于10^-5
    假设dp[i][j] 为A剩余i份 B剩余j份时 需要求的概率
    dp[i][j] = (dp[i-4][j]+dp[i-3][j-1]+dp[i-2][j-2]+dp[i-1][j-3])/4
    当j=0,i>0时 dp[i][j] = 0
    当i=0,j>0时 dp[i][j] = 1
    当i=0,j=0时 dp[i][j] = 0.5

    def soupServings(n):
        """
        :type n: int
        :rtype: float
        """
        n = (n+24)//25
        if n>=179:
            return 1
        dp = [[0]*(n+1) for _ in range(n+1)]
        dp[0] = [0.5]+[1.0]*n
        for i in range(1,n+1):
            for j in range(1,n+1):
                dp[i][j] = (dp[max(0, i - 4)][j] + 
                              dp[max(0, i - 3)][max(0, j - 1)] +
                                dp[max(0, i - 2)][max(0, j - 2)] + 
                                    dp[max(0, i - 1)][max(0, j - 3)])/4
        return dp[n][n]
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    11/22 878. 第 N 个神奇数字

    f(x)表示小于等于x内的神奇数字数目 c为a,b最小公倍数lcm
    f(x)=x//a+x//b-x//c
    f(x)随x增加单调不减 所以可以二分查找第n个神奇数字

    def nthMagicalNumber(n, a, b):
        """
        :type n: int
        :type a: int
        :type b: int
        :rtype: int
        """
        def lcm(a,b):
            x,y = a,b
            if a<b:
                x,y = b,a
            while y>0:
                x,y = y,x%y
            return a*b/x
        MOD = 10**9+7
        l,r = min(a,b),min(a,b)*n
        c = lcm(a,b)
        while l<=r:
            mid = (l+r)>>1
            s = mid//a+mid//b-mid//c
            if s>=n:
                r = mid-1
            else:
                l = mid+1
        return (r+1)%MOD
    
    
    
    • 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

    11/23 1742. 盒子中小球的最大数量

    用map存储每个盒子内的小球数

    def countBalls(lowLimit, highLimit):
        """
        :type lowLimit: int
        :type highLimit: int
        :rtype: int
        """
        def func(x):
            tag = 0
            while x>0:
                tag += x%10
                x = x//10
            return tag
        dic = {}
        ans = 0
        for i in range(lowLimit,highLimit+1):
            tag = func(i)
            dic[tag] = dic.get(tag,0)+1
            if dic[tag]>ans:
                ans = dic[tag]
        return ans
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    11/24 795. 区间子数组个数

    子数组最大值不能大于right 且范围内至少有一个处于[left,right]间
    l表示上次出现大于right的位置
    r表示上次出现left,right之间的位置
    对于当前位置i 可以有r-l个选择
    遍历每一个位置可以得到答案

    def numSubarrayBoundedMax(nums, left, right):
        """
        :type nums: List[int]
        :type left: int
        :type right: int
        :rtype: int
        """
        ans = 0
        l,r = -1,-1
        for i,num in enumerate(nums):
            if left<=num<=right:
                r = i
            elif num>right:
                l = i
                r = -1
            if r!=-1:
                ans += r-l
        return ans
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    11/25 809. 情感丰富的文字

    func 将字符串中连续相同的字母压缩成一个字母+出现的次数
    比较原始s和需要比较的字符串w 压缩后的状态
    需要满足 长度相等 每个位置上的字母需要一样
    出现的次数 s和w相同 或者s>w 并且s的次数大于等于3

    def expressiveWords(s, words):
        """
        :type s: str
        :type words: List[str]
        :rtype: int
        """
        def func(s):
            l = []
            cur = ""
            num = 0
            for c in s:
                if cur=="":
                    cur = c
                    num=1
                elif cur==c:
                    num+=1
                else:
                    l.append((cur,num))
                    cur = c
                    num = 1
            l.append((cur,num))
            return l
        sl = func(s)
        ans = 0
        for w in words:
            wl = func(w)
            if len(wl)!=len(sl):
                continue
            tag = True
            for i in range(len(sl)):
                if sl[i][0]!=wl[i][0]:
                    tag = False
                    break
                if wl[i][1]==sl[i][1] or (sl[i][1]>wl[i][1] and sl[i][1]>=3):
                    continue
                else:
                    tag = False
                    break
            if tag:
                ans+=1
        return ans
    
    
    
    • 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

    11/26 882. 细分图中的可到达节点

    原始节点间的细分节点数可看做节点间的距离
    使用dijkstra 可以算出起点到个点的最短路径 记录可达的原始节点数
    哈希表used[(u,v)]记录节点u到v可达的细分节点 (v,u)记录v到u可达的细分节点
    最后统计时相加 并不大于u,v间的细分节点总数

    def reachableNodes(edges, maxMoves, n):
        """
        :type edges: List[List[int]]
        :type maxMoves: int
        :type n: int
        :rtype: int
        """
        import heapq
        from collections import defaultdict
        l = defaultdict(list)
        for u,v,n in edges:
            l[u].append([v,n])
            l[v].append([u,n])
        used = {}
        visited = set()
        ans = 0
        pq = [(0,0)]
        heapq.heapify(pq)
        while pq and pq[0][0]<=maxMoves:
            step,u = heapq.heappop(pq)
            if u in visited:
                continue
            visited.add(u)
            ans +=1
            for v,nodes in l[u]:
                if nodes+step+1<=maxMoves and v not in visited:
                    heapq.heappush(pq,[nodes+step+1,v])
                used[(u,v)] = min(nodes,maxMoves-step)
        for u,v,n in edges:
            ans += min(n,used.get((u,v),0)+used.get((v,u),0))
        return ans
    
    
    
    • 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

    11/27 1752. 检查数组是否经排序和轮转得到

    原数组所有元素非递减排列
    假设轮转x个位置
    source[x,…,n-1]+source[0,…,x-1] = nums
    找到nums[i-1] 检查0~i-1 i~n-1是否都非递减

    def check(nums):
        """
        :type nums: List[int]
        :rtype: bool
        """
        n= len(nums)
        x = 0
        for i in range(1,n):
            if nums[i]<nums[i-1]:
                x=i
                break
        if x==0:
            return True
        for i in range(x+1,n):
            if nums[i]<nums[i-1]:
                return False
        return nums[0]>=nums[-1]
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

  • 相关阅读:
    英语没学好到底能不能做coder,别再纠结了先学起来
    雷电模拟器frida脱壳
    5 分钟理解 Next.js Static Export
    并查集&LRUCache
    KekeBlog项目实战后台模块(二)(已完结)
    迁移学习是什么?
    有想去做的事,早早去做
    宝塔面板建站
    申请宣告专利权无效的主体有哪些 ?
    STM32 M3M4 MCU与FreeRTOS 中断优先级配置
  • 原文地址:https://blog.csdn.net/zkt286468541/article/details/128012014