【Leetcode】二分查找合集

二分查找合集

二分模板

leetcode 704.二分查找

题目

思路

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

代码

java 复制代码
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;
    }
}

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

题目

思路

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

代码

java 复制代码
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;
    }
}

35. 搜索插入位置

题目

思路

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

代码

java 复制代码
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;
    }
}

69.X的平方根

题目

思路

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

代码

java 复制代码
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;
    }
}

852. 山脉数组的峰顶索引

题目

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

代码

java 复制代码
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;
    }
}

162.寻找峰值

题目

思路

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

代码

java 复制代码
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;
    }
}

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

题目

思路

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

代码

java 复制代码
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];
    }
}

LCR 173.点名

题目

思路

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

代码

java 复制代码
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;
    }
}
相关推荐
积兆科技23 分钟前
从汽车企业案例看仓网规划的关键步骤(视频版)
人工智能·算法·汽车·制造
Lenyiin1 小时前
01.01、判定字符是否唯一
算法·哈希算法
闻缺陷则喜何志丹1 小时前
【C++动态规划】1458. 两个子序列的最大点积|1823
c++·算法·动态规划·力扣·最大·子序列·点积
三万棵雪松1 小时前
3.系统学习-熵与决策树
学习·算法·决策树
半盏茶香1 小时前
C语言勘破之路-最终篇 —— 预处理(上)
c语言·开发语言·数据结构·c++·算法
2401_858286112 小时前
118.【C语言】数据结构之排序(堆排序和冒泡排序)
c语言·数据结构·算法
不会kao代码的小王2 小时前
从零开始搭建 AI 音乐生成器:MusicGPT 的超简单部署指南
科技·算法·开源·powerpoint
就爱学编程2 小时前
重生之我在异世界学编程之数据结构与算法:单链表篇
数据结构·算法·链表
88号技师9 小时前
2024年12月一区SCI-加权平均优化算法Weighted average algorithm-附Matlab免费代码
人工智能·算法·matlab·优化算法
IT猿手9 小时前
多目标应用(一):多目标麋鹿优化算法(MOEHO)求解10个工程应用,提供完整MATLAB代码
开发语言·人工智能·算法·机器学习·matlab