二分查找 常见题目

注:排序数组的查找问题首先考虑使用 二分法 解决,其可以将遍历法的线性级别时间复杂度降低到 对数级别

1. 找到第一个大于K的元素

nums = [5,7,7,8,8,9,10,10]
target =8

left,right = 0,len(nums)-1
while(left<=right):
    mid = left+(right-left)//2   
    if nums[mid]<=target:
        left = mid+1
    elif nums[mid]>target:
        right = mid-1
left

 2. 找到最后一个 ≤k的元素

nums = [5,7,7,8,8,9,10,10]
target =8

left,right = 0,len(nums)-1
while(left<=right):
    mid = left+(right-left)//2   
    if nums[mid]<=target:
        left = mid+1
    elif nums[mid]>target:
        right = mid-1
right

 3. 找到第一个≥k的元素

nums = [5,7,7,8,8,9,10,10]
target =8

left,right = 0,len(nums)-1
while(left<=right):
    mid = left+(right-left)//2   
    if nums[mid]<target:
        left = mid+1
    elif nums[mid]>=target:
        right = mid-1
left

4. 找到最后一个小于k的元素

nums = [5,7,7,8,8,9,10,10]
target =8

left,right = 0,len(nums)-1
while(left<=right):
    mid = left+(right-left)//2   
    if nums[mid]<target:
        left = mid+1
    elif nums[mid]>=target:
        right = mid-1
right

一、在有序数组中找到 数字K出现的次数

第一种解法:

1. 找到最后一个 小于k 的数字的坐标 l ;

2. 找到第一个 大于k 的数字的坐标 r ;

3. 则 数字k的个数为:r-l-1

第二种解法:

1. 找到 第一个大于k的元素r

2. 找到第一个大于k-1的元素l

3. 则k的个数为 r-l

class Solution:
    def search(self, nums: List[int], target: int) -> int:

        def searchleft(target):
            left,right = 0,len(nums)-1
            while(left<=right):
                mid = left+(right-left)//2   
                if nums[mid]<=target:
                    left = mid+1
                elif nums[mid]>target:
                    right = mid-1
            return right    

        l = searchleft(target-1)
        r = searchleft(target)
        return r-l

二、旋转数组的最小数字

1.  变成一个二分查找问题

2.  判断numbers[mid] 和numbers[r] 的关系

        如果 numbers[mid]  > numbers[r]  :   则最小值一定在 [mid+1,j]区间内

        如果 numbers[mid]  < numbers[r]  :   则最小值一定在 [l,mid]区间内

        如果 numbers[mid]  == numbers[r]  :   则最小值无法判断在那个区间,直接缩小 j 的范围   ,令 j = j-1   

class Solution:
    def minArray(self, numbers: List[int]) -> int:
        if len(numbers)==0:
            return 
        if len(numbers)==1:
            return numbers[0]
        
        l,r = 0,len(numbers)-1
        while(l<r):
            mid = l + (r-l)//2
            if numbers[mid]>numbers[r]:
                l = mid+1
            elif numbers[mid]<numbers[r]:
                r = mid
            else:
                r-=1
        return numbers[l]

猜你喜欢

转载自blog.csdn.net/yn20000227/article/details/125902328
今日推荐