当前位置: 首页 > news >正文

二分查找(java)

文章目录

    • 1. 基本原理
    • 2. 步骤
    • 3.练习

1. 基本原理

  二分查找(Binary Search)是一种基于分治思想的高效搜索算法,核心逻辑是通过不断缩小搜索区间来定位目标值。其前提是数据必须为有序数组,时间复杂度为 O(log n)。

2. 步骤

1. 初始化区间:左边界 left=0,右边界 right=数组长度-1。
2. 计算中间位置 mid = left + (right - left) >> 1(防止整数溢出)。
3. 比较 arr[mid] 与目标值:
	 -若相等,返回 mid;
	 -若目标值较小,调整右边界 right = mid - 1;
	 -若目标值较大,调整左边界 left = mid + 1。
4. 重复步骤2-3,直到 left > right,返回未找到标志(如 -1)。

3.练习

题目1:
在这里插入图片描述
解题思路:
  由于题目中是升序且无重复数组,可以利用二分法。因为在数组中找不到target时需要给出插入的位置,所有采用左开右闭。

class Solution {
    public int searchInsert(int[] nums, int target) {
        int len = nums.length;
        int ans = len;

        int left = 0, right = len-1;
        while(left <= right) {
            int mid = ((right - left) >> 1) + left;
            if(nums[mid] < target) {
                left = mid+1;
            }else {
                ans = mid;
                right = mid-1;
            }
            
        }

        return ans;
    }
}

题目2:
在这里插入图片描述
解题思路:
  题中可能存在三种情况:

   1. target在数组范围的左边或者右边,即target比最小值小或比最大值大;
   2. target在数组中存在;
   3. target在数组范围内,但数组中无target。

class Solution {
    public int[] searchRange(int[] nums, int target) {
        int leftBorder = search(nums, target, true);
        int rightBorder = search(nums, target, false);

        //target在数组范围左边或右边,即左右边界无效
        if(leftBorder == nums.length) {
            return new int[]{-1, -1};
        }
        //target在数组中存在
        if(rightBorder >= leftBorder) {
            return new int[]{leftBorder, rightBorder};
        }
        //target在数组中不存在
        return new int[]{-1, -1};

    }

    public int search(int[] nums, int target, boolean isLeft) {
        int n = nums.length;
        int ans = n;//n=1时,左右边界为0,1

        int left = 0, right = n-1;
        while(left <= right) {
            int mid = ((right - left) >> 1) + left;
            if(nums[mid] > target || (isLeft && nums[mid] >= target)) {
                ans = mid;
                right = mid-1;
            }else {
                left = mid+1;
            }
        }
        return isLeft ? ans : ans-1;
    }
}

题目3:
在这里插入图片描述
解题思路:
  题目要求找平方根,可以当作在升序整数数列中找某个值,所有可以用左闭右开二分法。

class Solution {
    public int mySqrt(int x) {
        if(x == 0) return 0;

        int ans = 0;
        int left = 1, right = x;
        while(left <= right) {
            int mid = left + ((right - left) >> 1);
            // 避免溢出
            if(mid > x/mid) {
                right = mid-1;
            }else {
                ans = mid;
                left = mid+1;
            }
        }
        return ans;
    }
}

题目4:
在这里插入图片描述
解题思路:
  要求判断有效,即严格要求存在平方根,所有要判断找出的ans是否有效。

class Solution {
    public boolean isPerfectSquare(int num) {
        int left = 1, right = num, ans = 0;

        while(left <= right) {
            int mid = left + ((right - left) >> 1);
            if(mid > num/mid) {
                right = mid - 1;
            }else {
                ans = mid;
                left = mid + 1; 
            }
        }

        return (double)num / ans / ans == 1;
    }
}

相关文章:

  • 大模型金融企业场景落地应用
  • 2021陇剑杯取证
  • [学习笔记]攻防世界-bug
  • 绿色暴政:Relax Max如何用军工科技定义环保新标准
  • 分布式数据集容错性两种方式解析
  • PTA | 连续因子
  • 迁移mysql8到达梦8
  • 护网(蓝中)DNS面试题
  • idea中快速注释函数
  • 2025蓝桥杯JAVA编程题练习Day7
  • YARN Cluster模式和Client模式的区别是什么
  • 若依框架二次开发——启动 RuoYi-Cloud 微服务项目
  • Go常见问题与答案笔记
  • Event driven agentic document workflows 笔记 - 4
  • Redis之大key问题
  • hackthebox1:入门
  • 19,C++——11
  • LeetCode热题100精讲——Top5:盛最多水的容器【双指针】
  • 微服务 - 高级篇
  • NSSRound(持续更新)
  • 广药集团原董事长李楚源被“双开”:去年8月被查,曾多次发表争议言论
  • 没有握手,采用翻译:俄乌三年来首次直接会谈成效如何?
  • 福州一宋代古墓被指沦为露天厕所,仓山区博物馆:已设置围挡
  • 刘国中将出席第78届世界卫生大会并顺访瑞士、访问白俄罗斯
  • 中国物流集团等10家央企11名领导人员职务任免
  • 独家 |《苏州河》上海上演,编剧海飞:上海的风能吹透我