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