为什么bisect_left比我在python3中的实现快

ddrv8njm  于 2023-05-02  发布在  Python
关注(0)|答案(1)|浏览(221)

我试图解决这个question和我的二进制搜索的实现超过了时间限制。当我使用bisect_left时,它运行得更快并且被接受。下面是我的方法。

def bs(self,new,k,n):
    st=0
    end=n
    while st<end:
        mid=(st+end)//2
        if new[mid]<k:
            st=mid+1
        else:
            end=mid
    return st
def smallerSum(self, n : int, arr : List[int],val) -> List[int]:
    new = sorted(arr)
    cum=[0 for _ in range(n+1)]
    for i in range(0,n):
        cum[i+1]=cum[i]+new[i]

    ans=[0 for _ in range(n)]
    for i in range(n):
        if val==0:
            ans[i] = cum[bisect_left(new,arr[i])]
        else:
            ans[i]= cum[self.bs(new,arr[i],n)]
    return ans

我试图测量10^5个随机整数的时间,我的实现所花费的时间大约是。33秒,而bisect_left只需要0秒。13秒我用来测量时间的完整代码

from typing import List
from bisect import bisect_left,bisect_right
import random
import time
class Solution:
    def bs(self,new,k,n):
        st=0
        end=n
        while st<end:
            mid=(st+end)//2
            if new[mid]<k:
                st=mid+1
            else:
                end=mid
        return st
    def smallerSum(self, n : int, arr : List[int],val) -> List[int]:
        new = sorted(arr)
        cum=[0 for _ in range(n+1)]
        for i in range(0,n):
            cum[i+1]=cum[i]+new[i]

        ans=[0 for _ in range(n)]
        for i in range(n):
            if val==0:
                ans[i] = cum[bisect_left(new,arr[i])]
            else:
                ans[i]= cum[self.bs(new,arr[i],n)]
        return ans
if __name__=="__main__":
    n = 10**5
    arr=[]
    for i in range(n):
        arr.append(random.randint(0,10**9))
    obj = Solution()
    st=time.time()
    res = obj.smallerSum(n,arr,0)
    end=time.time()
    print(end-st)
    st=time.time()
    res = obj.smallerSum(n,arr,1)
    end=time.time()
    print(end-st)

为什么会有这样的时间差,为什么bisect_left更快?

wb1gzix0

wb1gzix01#

如@SuperStormer www.example.com python3使用更快的C实现,这就是为什么bisect_left需要更少的时间。

相关问题