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] + " ");
        }
    }
}
相关推荐
魔道不误砍柴功13 分钟前
Java 中如何巧妙应用 Function 让方法复用性更强
java·开发语言·python
NiNg_1_23413 分钟前
SpringBoot整合SpringSecurity实现密码加密解密、登录认证退出功能
java·spring boot·后端
pianmian114 分钟前
python数据结构基础(7)
数据结构·算法
闲晨16 分钟前
C++ 继承:代码传承的魔法棒,开启奇幻编程之旅
java·c语言·开发语言·c++·经验分享
测开小菜鸟2 小时前
使用python向钉钉群聊发送消息
java·python·钉钉
好奇龙猫2 小时前
【学习AI-相关路程-mnist手写数字分类-win-硬件:windows-自我学习AI-实验步骤-全连接神经网络(BPnetwork)-操作流程(3) 】
人工智能·算法
P.H. Infinity3 小时前
【RabbitMQ】04-发送者可靠性
java·rabbitmq·java-rabbitmq
生命几十年3万天3 小时前
java的threadlocal为何内存泄漏
java
sp_fyf_20243 小时前
计算机前沿技术-人工智能算法-大语言模型-最新研究进展-2024-11-01
人工智能·深度学习·神经网络·算法·机器学习·语言模型·数据挖掘
caridle3 小时前
教程:使用 InterBase Express 访问数据库(五):TIBTransaction
java·数据库·express