LeetCode——二分查找(Java)

二分查找

  • 简介
  • 704.二分查找
  • [35. 搜索插入位置](#35. 搜索插入位置)
  • [34. 在排序数组中查找元素的第一个和最后一个位置](#34. 在排序数组中查找元素的第一个和最后一个位置)

简介

记录一下自己刷题的历程以及代码,会尽量把在本地测试包含main函数的完整代码贴上,以及一些注释掉的输出语句。写题过程中参考了 代码随想录。会附上一些个人的思路,如果有错误,可以在评论区提醒一下。

704.二分查找

原题链接
right = nums.length - 1;是一种闭区间的写法,左右下标都在数组范围内,此时while循环中需要加上=,否则会在nums = [5],target = 5的情况下报错。

java 复制代码
class Solution {
    public int search(int[] nums, int target){
        if(target<nums[0] || target>nums[nums.length-1]){
            return -1;
        }
        int left = 0;
        int right = nums.length - 1;
        int mid = 0;
        while(left <= right){
            //System.out.println("left:" + left + "  mid:" + mid + "  right:" + right);
            mid = (left + right) / 2;
            if(target > nums[mid]) {
                left = mid + 1;
            }else if(target < nums[mid]){
                right = mid - 1;
            }else{
                return mid;
            }
        }
        return -1;
    }
}

public class main {
    public static void main(String[] args) {
        Solution solution = new Solution();
        int[] nums = new int[]{-1,0,3,5,9,12};
        int target = 9;
        System.out.println(solution.search(nums,target));
    }
}

35. 搜索插入位置

原题链接

总共四种情况

①找到元素,返回middle

找不到元素,循环正常退出,此时有right = left-1

②在所有元素之前,此时left = 0;right = -1 target需要插入0,即left的位置

③在两个元素中间,此时nums[left]>target;nums[right]<targettarget需要插入left的位置

④在所有元素之后,此时right=nums.length()-1;left=nums.length()target需要插入left的位置

java 复制代码
class Solution {
    public int searchInsert(int[] nums, int target) {
        int left = 0;
        int right = nums.length - 1;
        int mid = 0;
        while(left <= right){
            mid = (left + right) / 2;
            //System.out.println("left:" + left + "  mid:" + mid + "  right:" + right);
            if(target > nums[mid]) {
                left = mid + 1;
            }else if(target < nums[mid]){
                right = mid - 1;
            }else{
                return mid;
            }
        }
        return left;
    }
}

public class main {
    public static void main(String[] args) {
        Solution solution = new Solution();
        int[] nums = new int[]{1,3};
        int target = 0;
        System.out.println(solution.searchInsert(nums,target));
    }
}

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

原题链接

方法一:找到nums[mid] == target时在mid左右继续查找相等的值,在二分查找的代码上增加一些功能即可,但是当连续的数字过多时容易将复杂度退到O(n),相当于遍历的复杂度。可以通过这道题,但是时间复杂度较高。

方法二:分别寻找左右边界,左边界指向 该元素第一个位置之前的元素,右边界指向最后一个位置之后的元素。

例如找左边界:nums[mid] == target时也要把范围划到mid左边,因为我们需要找的是target的边界

java 复制代码
int left = 0;
int right = nums.length - 1;
int leftBorder = -2;
while(left <= right){
    if(target > nums[mid]) {
        left = mid + 1;
    }else if(target < nums[mid]){
        right = mid - 1;
        leftBorder = right;
    }else if(target == nums[mid]){
        right = mid - 1;
        leftBorder = right;
    }
}

查找左右边界的函数内部的判断语句是由上面的判断语句三种情况合并而成,结果如下:

java 复制代码
class Solution {
    public int[] searchRange(int[] nums, int target) {
        int leftBorder = searchLeft(nums, target);
        int rightBorder = searchRight(nums, target);
        if(leftBorder == -2 || rightBorder == -2) return new int[]{-1 ,-1};
        if(rightBorder - leftBorder > 1) return new int[]{leftBorder + 1,rightBorder - 1};
        return new int[]{-1 ,-1};
    }

    public int searchLeft(int[] nums, int target){
        int left = 0;
        int right = nums.length - 1;
        int leftBorder = -2;
        while(left <= right){
            int mid = (left + right) / 2;
            if(target > nums[mid]) {
                left = mid + 1;
            }else{
                right = mid - 1;
                leftBorder = right;
            }
        }
        return leftBorder;
    }

    public int searchRight(int[] nums, int target){
        int left = 0;
        int right = nums.length - 1;
        int rightBorder = -2;
        while(left <= right){
            int mid = (left + right) / 2;
            if(target < nums[mid]) {
                right = mid - 1;
            }else{
                left = mid + 1;
                rightBorder = left;
            }
        }
        return rightBorder;
    }


}

public class main {
    public static void main(String[] args) {
        Solution solution = new Solution();
        int[] nums = new int[]{2, 2};
        int target = 3;
        int[] array = solution.searchRange(nums,target);
        for (int i = 0; i < array.length; i++) {
            System.out.print(array[i] + " ");
        }
    }
}
相关推荐
LayZhangStrive9 分钟前
融360 一面
java·面试·后端开发
学习中.........20 分钟前
Karpathy nanoGPT 教程到底讲了什么
人工智能·算法·语言模型
城管不管34 分钟前
重生——第十次面试之开源中国一面挂
java·linux·开发语言·算法·面试·职场和发展·开源
Java小白笔记38 分钟前
Windows系统免软件命令激活
java·网络·人工智能·windows·ai·ai编程
爱敲键盘的猴子1 小时前
深入理解 Java HashMap
java·hashmap
霸道流氓气质1 小时前
Java开发者AI编程常用MCP、Skills、Rules全景汇总
java·开发语言·ai编程
天涯醉青楼1 小时前
Spring Boot 接口返回 Bean 时字段名“变形”的深度剖析与解决方案
java
步行cgn1 小时前
MyBatis 高级映射与延迟加载完全指南
java·tomcat·mybatis
thefool1122661 小时前
从中序与后序遍历序列构造二叉树
java
吴声子夜歌1 小时前
Java面试题——JVM(二)
java·开发语言·jvm