LeetCode-【二分查找】解题技巧

5489. 两球之间的磁力

分析:

题意求最大化最小,类似这样的求最大化最小值、最小化最大值等都可以用二分搜索解决.

1.找到所有position的最大距离和最小距离;

2.通过二分法,分别判断满足条件的距离(a.mid=(最大距离+最小距离)/2;b.满足条件的点是否>=m);

下面是实现示例:

class Solution(object):
    def check(self,p,mid,m):
        c = 0
        i,j=0,1
        while j<len(p):
            if p[j] - p[i] >= mid:
                c+=1
                i=j
            j+=1
        return c+1>=m

    def maxDistance(self, position, m):
        """
        :type position: List[int]
        :type m: int
        :rtype: int
        """
        position = sorted(position)
        min_d = position[-1] - position[0]
        max_d = position[-1] - position[0]
        for i in range(len(position)-1):
            if min_d > position[i+1] - position[i]:
                min_d = position[i+1] - position[i]
        if m == 2:
            return max_d
        left,right = min_d,max_d
        while left<=right:
            mid = (left+right)/2
            if self.check(position,mid,m):
                left=mid+1
            else:
                right=mid-1
        return left-1

6010. 完成旅途的最少时间

class Solution:
    def minimumTime(self, time: List[int], totalTrips: int) -> int:
        time.sort()
        left = 0
        right = time[0]*totalTrips
        while left<right:
            mid = (left+right)//2
            trips = 0
            for t in time:
                if t>mid:
                    break
                trips += mid//t
            if trips>=totalTrips:
                right = mid
            else:
                left=mid+1            
        return left

911. 在线选举

此题使用二分才能通过。重点在于,根据题目,将问题转换成二分,

class TopVotedCandidate:

    def __init__(self, persons: List[int], times: List[int]):
        maxid = -1
        self.p_c = {}
        self.t_p = {}
        self.t = times
        for i,v in enumerate(persons):
            self.p_c[v] = self.p_c.get(v,0)+1
            max_c = self.p_c.get(maxid,0)
            if self.p_c[v] >= max_c:
                maxid = v
            self.t_p[times[i]] = maxid
    def q(self, t: int) -> int:
        l = 0
        r = len(self.t)-1
        while l<=r:
            m = (l+r)//2
            if t>=self.t[m]:
                l=m+1
            else:
                r=m-1
        return self.t_p[self.t[l-1]]


# Your TopVotedCandidate object will be instantiated and called as such:
# obj = TopVotedCandidate(persons, times)
# param_1 = obj.q(t)

611. 有效三角形的个数

边排序后,确定2条较长边,然后通过二分法找最后一条边的范围。

class Solution:
    def triangleNumber(self, nums: List[int]) -> int:
        nums.sort()
        L = len(nums)
        ret = 0
        for i in range(L):
            for j in range(i-1,-1,-1):
                l = 0
                r = j-1
                while l<=r:
                    m = (l+r)//2
                    if nums[m]+nums[j]>nums[i]:
                        r=m-1
                    else:
                        l=m+1
                ret += (j-1-r)
        return ret

274. H 指数

此题核心是确定h指数为二分查找对象,二分每确定一个值,就判断一次是否满足要求;

class Solution:
    def check(self,cs,m):
        t = 0
        for i in cs:
            if i>=m:
                t+=1
        return t>=m

    def hIndex(self, citations: List[int]) -> int:
        l = 0
        r = len(citations)
        while l<=r:
            m = (l+r)//2
            if self.check(citations,m):
                l=m+1
            else:
                r=m-1
        return l-1

1482. 制作 m 束花所需的最少天数

最主要的核心是获取最大最小天数,然后将天数进行二分,分别判断不同天数是否满足要求。

class Solution:

    def check(self,arr,mid,m,k):
        t = 0
        ret = 0
        for i in arr:
            if i<=mid:
                t+=1
            else:
                ret+=(t//k)
                t=0
        ret += (t//k)
        return ret>=m

    def minDays(self, bloomDay: List[int], m: int, k: int) -> int:
        l = min(bloomDay)
        r = max(bloomDay)
        min_ = l
        max_ = r

        while l<=r:
            mid = (l+r)//2
            if self.check(bloomDay,mid,m,k):
                r=mid-1
            else:
                l=mid+1
        if l>max_ or l<min_:
            return -1
        return l

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值