• 力扣704题、34题(二分查找)


    704、二分查找

    基本思想:

    • 如果目标值等于中间元素,则找到目标值。
    • 如果目标值较小,继续在左侧搜索。
    • 如果目标值较大,则继续在右侧搜索。

    具体实现:

    1、搜索时是在闭区间[left,right],target定义在这个区间内

    初始化right的赋值是len(nums)-1,是最后一个元素的索引,

    • while循环中的条件是<=  不是=
    • if (nums[middle] >targrt)   right = middle-1
    • if (nums[middle] < target) left = middle +1

    2、搜索时在半开半闭区间[left,right),target定义在这个区间

    初始化right的赋值是len(nums)

    • while循环中的条件是<  不是<=,因为left == right在区间[left,right)无意义
    • if (nums[middle] >targrt)   right = middle,去左区间寻找,而寻找区间是左闭右开的,所以right更新为middle
    • if (nums[middle] < target) left = middle +1

    代码:

    class Solution:
        def search(self, nums: List[int], target: int) -> int:
            left = 0
            right = len(nums) - 1
            while left <= right:
                mid = int(left + (right-left)/2)
                # mid = left + (right-left)//2
                if nums[mid] == target:
                    return mid
                elif nums[mid] < target:
                    left = mid + 1
                elif nums[mid] > target:
                    right = mid -1
            return -1

    第一种情况

    class Solution {
        public int search(int[] nums, int target) {
            if (target < nums[0] || target > nums[nums.length -1]){
                return -1;
            }
            int left = 0, right = nums.length - 1;
            while (left <= right){
                int mid = left + ((right - left) >> 1);
                if (nums[mid] == target){
                   return mid; 
                }
                else if (nums[mid] < target) {
                    left = mid +1;
                }
                else {
                    right = mid - 1;
                }
            }
            return -1;
        }
    }

    第二种情况

    class Solution {
        public int search(int[] nums, int target) {
            if (target < nums[0] || target > nums[nums.length -1]){
                return -1;
            }
            int left = 0, right = nums.length;
            while (left < right){
                int mid = left + ((right - left) >> 1);
                if (nums[mid] == target){
                   return mid; 
                }
                else if (nums[mid] < target) {
                    left = mid +1;
                }
                else {
                    right = mid ;
                }
            }
            return -1;
        }
    }

    34、在排序数组中查找元素的第一个和最后一个元素

    基本思想:

    寻找左侧边界的二分搜索

    具体实现:

    1.二分搜索中没有return -1,如果nums中不存在target这个值,还是会返回left

    eg nums=[2,3,5,7]

    target = 1,返回0,含义是nums中小于1的个数有0个

    target = 8,返回4,含义是nums中小于8的个数有4个

    这些返回的数会送去验证,验证是否是目标数

    2、nums=[5,7,7,8,8,10] target=8

    先得出靠左侧的8的下标=3,赋值给a

    再让target+1=9,

    没有找到9,但是会返回nums中比9小的数的个数有5个

    返回5,赋值给b

    3、第一个大于target的位置-1

    得出答案[3,4]

    4、假如找不到target,进行验证后返回[-1,-1]

    代码:

    class Solution(object):
        def searchRange(self,nums, target):
            """
            :type nums: List[int]
            :type target: int
            :rtype: List[int]
            """
            def left_func(nums,target):
                n = len(nums)
                left = 0
                right = n -1
                while(left <= right):
                    mid = left + (right-left) // 2
                    if nums[mid] >= target:
                        right = mid - 1
                    if nums[mid] < target:
                        left = mid + 1
                return left
            a =  left_func(nums,target)
            b = left_func(nums,target+1)
            if  a == len(nums) or nums[a] != target:
                return [-1,-1]
            else:
                return [a,b-1]

    java

    class Solution {
        public int[] searchRange(int[] nums, int target) {
            int a = binarySearch(nums, target);
            int b = binarySearch(nums, target + 1);
            if (a == nums.length || nums[a] != target){
                return new int[]{-1,-1};
            }
            else{
                return new int[]{a,b-1};
            }
        }
        public int binarySearch(int[] nums, int target){
            int n = nums.length;
            int left = 0, right = n - 1;
            while (left <= right){
                int mid = left + ((right - left) >> 1);
                if (nums[mid] >= target){
                    right = mid - 1; 
                }
                else  {
                    left = mid +1;
                }
            }
            return left;
            
        
        }
    }
  • 相关阅读:
    Unicode下CString(wchar_t)转换为 char*
    安装程序制作(转)
    STL头文件
    杭电2043 请大神帮我看看哪错了?谢谢了!
    杭电2046
    杭电2044
    实现winform中的treeview控件部分节点显示checkbox,部分节点不显示checkbox的功能
    实现将sqlserver2000的多张表导出到access,并压缩,并导入压缩的access文件到sqlserver2000
    从Excel中指定的sheet名称或索引读取数据到DataTable,以便用户更改sheet名称后仍能读取数据
    combobox控件实现多列显示
  • 原文地址:https://www.cnblogs.com/zhaojiayu/p/14522531.html
Copyright © 2020-2023  润新知