[Leetcode] 每日两题 786 1018 -day25

786. 第 K 个最小的素数分数

请添加图片描述

方法1 : 暴力 把所有的数字 以及分子分母都保存起来 ,然后 sort一下 再拿出第k个 如果用优先队列来做应该快很多 不过我没写

这样复杂度 O(n² log n²)
请添加图片描述请添加图片描述请添加图片描述

class Solution:
    def kthSmallestPrimeFraction(self, arr: List[int], k: int) -> List[int]:
        
        n = len(arr)
        re = []
        for i in range(n-1,-1,-1):
            for j in range(i):
                re.append((arr[j]/arr[i],arr[j],arr[i]))
        re.sort()
        return re[k-1][1:]

方法2 : 想到是找第k个数 那没必要把所有的数都排一遍 显然冗余

所以这种找第几个的东西 可以用 二分来做,

所有的分数值都是再 0- 1之间

那么找到一个0-1 之间的数 使得 比这个数小的数有k个就好了

对于每个 mid 分母 从小到大 进行遍历 ,分子也是

对于 分母 j 位置的 小于mid的所有分数, 对于分母j+1 这些分子来构成的分数同样满足,所以只要在最顶部开始判断,然后记得记录 每个分母位置的最大分数
请添加图片描述请添加图片描述请添加图片描述

class Solution:
    def kthSmallestPrimeFraction(self, arr: List[int], k: int) -> List[int]:
        n = len(arr)
        left, right = 0, 1
        while 1:
            mid = (left +right) /2
            count,j = 0,0
            x,y = 0,1
            for i in range(1,n):
                flag =0
                while arr[j]/arr[i] < mid:
                    #print(arr[j],arr[i],mid)
                    j += 1
                    flag =1
                # 保存该子集中最大的那个
                if flag==1 and arr[j-1]*y > arr[i]*x :
                        #print(arr[j],arr[i],x,y)
                        x,y =arr[j-1],arr[i]     
                count += j
            #print(count,x,y)
            if count == k:
                return[x,y]
            elif count > k:
                right = mid
            else:
                left = mid
1018. 可被 5 整除的二进制前缀

请添加图片描述

循环 每次 左移一个 然后加上末尾 再% 5 运算 记得每次都 % 5 这样num 一直很小 节省大量时间

class Solution:
    def prefixesDivBy5(self, nums: List[int]) -> List[bool]:
        re = []
        num =0
        for i in nums:
            num = ((num<<1) +i)%5  
            if num % 5 :
                re.append(False)
            else :
                re.append(True)
        return re
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值