• 【Leetcode】二分查找合集


    二分模板

    在这里插入图片描述

    leetcode 704.二分查找

    题目

    在这里插入图片描述

    思路

    1. 最简单的二分查找,直接套模板即可

    代码

    class Solution {
        public int search(int[] nums, int target) {
            int left = 0;
            int right = nums.length - 1;
            while(left <= right){
                int mid = left + (right - left) / 2;
                if(nums[mid] > target){
                    right = mid - 1;
                }else if(nums[mid] < target){
                    left = mid + 1;
                }else{
                    return mid;
                }            
            }
            return -1;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    Leetcode 34.在排序数组中查找元素的第⼀个和最后⼀个位置

    题目

    在这里插入图片描述

    思路

    1. 通过二分查找的方式,找到这段区间的左边界和右边界即可

    代码

    class Solution {
        public int[] searchRange(int[] nums, int target) {
            int left = 0;
            int right = nums.length - 1;
            int[] ret = {-1,-1};
            if(nums.length == 0){
                return ret;
            }
    
            //查找左边界
            while(left < right){
                int mid = left + (right - left) / 2;
                if(nums[mid] < target){
                    left = mid + 1;
                }else{
                    right = mid;
                }
            }
            if(nums[left] != target){
                return ret;
            }
            ret[0] = left;
            left = 0;
            right = nums.length - 1;
            //查找右边界
            while(left < right){
                int mid = left + (right - left + 1) / 2;
                if(nums[mid] <= target){
                    left = mid;
                }else{
                    right = mid - 1;
                }
            }
            ret[1] = right;
            return ret;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37

    35. 搜索插入位置

    题目

    在这里插入图片描述

    思路

    1. 题目要求使用logn 的时间复杂度,即明确表示使用二分查找来解决
    2. 根据插入元素的位置index,将数组分为两段,[left,index - 1]都是=target,我们只要找到第二个区间的左边界,即可找到插入位置,即使用找数组左区间的模板即可

    代码

    class Solution {
        public int searchInsert(int[] nums, int target) {
            int left = 0;
            int right = nums.length - 1;
            while(left < right){
                int mid = left + (right - left)/2;
                if(nums[mid] < target){
                    left = mid + 1;
                }else{
                    right = mid;
                }
            }
            if(nums[right] < target){
                return right + 1;
            }
            return left;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    69.X的平方根

    题目

    在这里插入图片描述

    思路

    1. 假设最终平方根的整数位为index ,则假设一个数组[1,x],其中都是整数,则可以分为两段,[1,index],这一段平方后都<=x,[index+1,right]这一段平方后都>x,这样分为两段,即可使用二分查找的方式,我们只需要找到第一段区间的右端点,即可求出index,此时套模板即可

    代码

    class Solution {
        public int mySqrt(int x) {
            if(x < 1){
                return 0;
            }
            long left = 1,right = x;
            while(left < right){
                long mid = left + (right - left + 1) / 2;
                if(mid * mid > x){
                    right = mid - 1;
                }else{
                    left = mid;
                }
            }
            return (int)left;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    852. 山脉数组的峰顶索引

    题目

    在这里插入图片描述

    1. 根据题意,我们可以将这个数组分为两段,一段升序一段降序,我们既可以根据这个条件,使用二分查找来解题
    2. 假设封顶索引为index,此时将数组分为[left,index - 1]和[index, right]两段,左半段arr[i+1] > arr[i],右半段arr[i+1] < arr[i], 此时我们只需要求出右区间的左端点即可得出index,套用模板即可
    3. 根据此题我们可以知道,二分查找不一定需要数组有序,而是可以根据已知条件,将数组划分为两段即可

    代码

    class Solution {
        public int peakIndexInMountainArray(int[] arr) {
            int left = 0;
            int right = arr.length - 1;
            while(left < right){
                int mid = left + (right - left) / 2;
                if(arr[mid+1] > arr[mid] ){
                    left = mid + 1;
                }else{
                    right = mid;
                }
            }
            return right;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    162.寻找峰值

    题目

    在这里插入图片描述

    思路

    1. 对于数组中的某个位置 mid,如果 nums[mid] > nums[mid+1],则说明峰值在 mid 的左侧(包括 mid 本身),如果 nums[mid] <= nums[mid+1],则说明峰值在 mid+1 的右侧。基于这个思路,我们可以使用二分查找来找到峰值。

    代码

    class Solution {
        public int findPeakElement(int[] nums) {
            int left = 0;
            int right = nums.length - 1;
            while(left < right){
                int mid = left + (right - left)/2;
                if(nums[mid+1] > nums[mid]){
                    left = mid + 1;
                }else{
                    right = mid;
                }
            }
            return right;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    153. 寻找旋转排序数组中的最小值

    题目

    在这里插入图片描述

    思路

    1. 题目告诉使用logn的时间复杂度解决问题,即使用二分查找的方式解决问题
    2. 二分的基本思路就是将数组分为两段,假设最小元素下标为index,则可以分为[left,index - 1],[index,right],第一段元素都大于等于right,第二段元素都小于right,根据这个特性就可以把数组分为两段,我们要找的元素就是第二段的左区间,套用模板即可

    代码

    class Solution {
        public int findMin(int[] nums) {
            int left = 0;
            int right = nums.length - 1;
            while(left < right){
                int mid = left + (right - left) / 2;
                if(nums[mid] > nums[right]){
                    left = mid + 1;
                }else{
                    right = mid;
                }
            }
            return nums[left];
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    LCR 173.点名

    题目

    在这里插入图片描述

    思路

    1. 升序数组查找元素优先考虑二分查找,
    2. 先考虑数组能否分为两段,观察得知假设我们要找的元素下表为index,则可以分为[left,index-1],[index,right],两段,其中第一段中数组在该下标中的值等于下标,而第二段则大于下标,此时我们转化为求第二段区间的左边界问题

    代码

    class Solution {
        public int takeAttendance(int[] records) {
            int left = 0;
            int right = records.length -1;
            if(records[records.length - 1] == records.length - 1){
                return records.length;
            }
            while(left < right){
                int mid = left + (right - left) / 2;
                if(records[mid] > mid){
                    right = mid;
                }else{
                    left = mid + 1;
                }
            }
            return left;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
  • 相关阅读:
    DataGrip 2023:让数据库开发变得更简单、更高效 mac/win
    论文笔记《Admix: Enhancing the Transferability of Adversarial Attacks》
    GitHub上标星120k的Java进阶面试教程等!(建议收藏)
    数据集笔记:芝加哥共享单车OD数据
    AntDesignPro快速入门
    【共享模型-----管程】
    springboot项目需要的依赖
    09 Ubuntu安装FreeCAD
    低代码物联网平台的业务应用场景有哪些?
    23. python 条件判断嵌套
  • 原文地址:https://blog.csdn.net/m0_72670269/article/details/133558671