二分查找算法的经典题目

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档

文章目录



前言

二分查找算法可以很快地找出数组中的某个元素或者是某个边界。



一、经典题目,找元素

/**
 * Created with IntelliJ IDEA.
 *
 * @author : Future master
 * @version : 1.0
 * @Project : Java算法联系
 * @Package : PACKAGE_NAME
 * @ClassName : Solution.java
 * @createTime : 2021/10/29 19:15
 * @Email : 2467636181@qq.com
 * 给定一个n个元素有序的(升序)整型数组nums 和一个目标值target,写一个函数搜索nums中的 target,如果目标值存在返回下标,否则返回 -1。
 * 来源:力扣(LeetCode)
 * 链接:https://leetcode-cn.com/problems/binary-search
 */
class Solution {
    public int search(int[] nums, int target) {//标准的二分查找
            int left = 0;//小心这个边界
            int right = nums.length-1;//小心这个边界
            int center;//先定义这个center应该有助于节省空间
            while(right >= left){//一定要写=
                center = left+((right-left)>>1);//使用位移可以提高性能
                if(nums[center]>target){//当中间值比目标值大的时候对左半边继续进行循环
                    right = center-1;
                    continue;
                }else if(nums[center]<target){//当中间值比目标函数值小的时候对右半边进行循环
                    left = center+1;
                    continue;
                }else{
                    return center;//当正好等于中间值的时候返回当前索引
                }
            }
            return -1;//如果没有找寻完当前数组仍然没有找到则,返回-1
    }

    public static void main(String[] args) {
        Solution solution = new Solution();
        int[] nums = {2,5};
        int target = 5;
        System.out.println(solution.search(nums,target));
    }
}


二、找边界

/**
 * Created with IntelliJ IDEA.
 *
 * @author : Future master
 * @version : 1.0
 * @Project : Java算法联系
 * @Package : PACKAGE_NAME
 * @ClassName : Solution.java
 * @createTime : 2021/10/29 20:23
 * @Email : 2467636181@qq.com
 * 你是产品经理,目前正在带领一个团队开发新的产品。不幸的是,你的产品的最新版本没有通过质量检测。由于每个版本都是基于之前的版本开发的,所以错误的版本之后的所有版本都是错的。
 *
 * 假设你有 n 个版本 [1, 2, ..., n],你想找出导致之后所有版本出错的第一个错误的版本。
 *
 * 你可以通过调用bool isBadVersion(version)接口来判断版本号 version 是否在单元测试中出错。实现一个函数来查找第一个错误的版本。你应该尽量减少对调用 API 的次数。
 * 来源:力扣(LeetCode)
 * 链接:https://leetcode-cn.com/problems/first-bad-version
 */
class VersionControl{//设定判断是否为失败版本的标准方法
    private int version;//失败版本号
    public void writeVersion(int version){
        this.version = version;//写入当前对象的版本号方法
    }
    public boolean isBadVersion(int version){
        if(version>=this.version){//当大于当前版本的时候即为失败版本
            return true;
        }
        return false;
    }
}
public class Solution1 extends VersionControl {
    public int firstBadVersion(int n) {//标准的二分查找,找边界
        int left = 0;
        int right = n;
        int center;
        while(left<=right){//当第一次left > right的时候即为边界,此时循环结束找到出口
            center = left+((right-left)>>1);
            if(isBadVersion(center)){//如果检测到当前中心位置为失败版本,应继续往前找
                right = center-1;
            }else{//如果当前版本不为失败版本应继续往后找
                left = center+1;
            }
        }
        return left;//返回此时的边界
    }

    public static void main(String[] args) {//测试
        int n = 5;
        int bad = 3;
        Solution1 solution1 = new Solution1();
        solution1.writeVersion(bad);
        System.out.println(solution1.firstBadVersion(n));
    }
}


三、找元素,若没有元素则找到插入的位置

/**
 * Created with IntelliJ IDEA.
 *
 * @author : Future master
 * @version : 1.0
 * @Project : Java算法联系
 * @Package : PACKAGE_NAME
 * @ClassName : Solution2.java
 * @createTime : 2021/10/29 21:01
 * @Email : 2467636181@qq.com
 * 给定一个排序数组和一个目标值,在数组中找到目标值,并返回其索引。如果目标值不存在于数组中,返回它将会被按顺序插入的位置。
 */
public class Solution2 {
    public int searchInsert(int[] nums, int target) {
            int left = 0;
            int right = nums.length-1;
            int center;
            while(right>=left){
                center = left+((right-right)>>1);
                if(nums[center]==target){
                    return center;
                }else if(nums[center]>target){
                    right = center-1;
                }else{
                    left = center+1;
                }
            }
            return left;//返回应该插入的地方
    }

    public static void main(String[] args) {
        int[] nums = {1, 3, 5, 8};
        int target = 6;
        Solution2 solution2 = new Solution2();
        System.out.println(solution2.searchInsert(nums,target));
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

躺平崽

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值