LeetCode--704.二分查找(数组)

题目描述

给定一个 n 个元素有序的(升序)整型数组 nums 和一个目标值 target ,写一个函数搜索 nums 中的 target,如果 target 存在返回下标,否则返回 -1

你必须编写一个具有 O(log n) 时间复杂度的算法。

示例 1:

复制代码
输入: nums = [-1,0,3,5,9,12], target = 9
输出: 4
解释: 9 出现在 nums 中并且下标为 4

示例 2:

复制代码
输入: nums = [-1,0,3,5,9,12], target = 2
输出: -1
解释: 2 不存在 nums 中因此返回 -1

提示:

  1. 你可以假设 nums 中的所有元素是不重复的。
  2. n 将在 [1, 10000]之间。
  3. nums 的每个元素都将在 [-9999, 9999]之间。

解题思路

这道题目的前提是数组为有序数组 ,同时题目还强调数组中无重复元素,因为一旦有重复元素,使用二分查找法返回的元素下标可能不是唯一的,这些都是使用二分法的前提条件,当大家看到题目描述满足如上条件的时候,可要想一想是不是可以用二分法了。

二分查找涉及的很多的边界条件,逻辑比较简单,但就是写不好。例如到底是 while(left < right) 还是 while(left <= right),到底是right = middle呢,还是要right = middle - 1呢?

大家写二分法经常写乱,主要是因为对区间的定义没有想清楚,区间的定义就是不变量 。要在二分查找的过程中,保持不变量,就是在while寻找中每一次边界的处理都要坚持根据区间的定义来操作,这就是循环不变量规则。

写二分法,区间的定义一般为两种,左闭右闭即left, right,或者左闭右开即[left, right)。

我个人倾向使用左闭右闭方法处理二分法。

如图所示,当我们使用左闭右闭即[left, right]时,就需要让right = middle - 1了。因为middle的值已经做过一次比较。

代码

java 复制代码
class Solution {
    public int search(int[] nums, int target) {
        
        int length = nums.length;
        // 左边下标初始为0
        int left = 0;
        // 记录右边下标,为数组长度 - 1
        int right = length - 1;
        // 避免当 target 小于nums[0] nums[nums.length - 1]时多次循环运算
        if (target < nums[0] || target > nums[length - 1]) {
            return -1;
        }
        // 使用左闭右闭即[left, right]区间
        while(left <= right){
             // 初始化中点 middle,以防溢出,用减法
             int middle = left + (right - left) / 2;
            // 比target大,right = middle - 1
            if(nums[middle] > target){
                right = middle - 1;
            } else if(nums[middle] < target){
                // 比target小,left = middle + 1
                left = middle + 1;
            } else{
                return middle;
            }
        }
        // 若left > right,要求的target数组中不存在
        return -1;
        
    }
}
相关推荐
怪兽学LLM5 分钟前
LeetCode 438 找到字符串中所有字母异位词(Python 固定滑动窗口+字符计数解法)
python·算法·leetcode
满怀冰雪10 分钟前
第04篇-双指针算法-从有序数组到回文判断的高频解法
java·算法
CC数学建模10 分钟前
2026年江西省研究生数学建模竞赛1题:空间数据分析中的过拟合识别完整思路、代码、模型、文章,全网首发高质量分享!
python·算法·数学建模
leo__52018 分钟前
MATLAB实现牧羊人算法
开发语言·算法·matlab
Gauss松鼠会24 分钟前
【GaussDB】GaussDB SMP特性调优详解
java·服务器·前端·数据库·sql·算法·gaussdb
Tisfy29 分钟前
LeetCode 3689.最大子数组总值 I:What The Medium
算法·leetcode·题解·贪心·模拟·脑筋急转弯
葬送的代码人生29 分钟前
JavaScript 数组完全指南:从入门到实战
前端·javascript·算法
春日见44 分钟前
决策规划控制面经汇总
人工智能·深度学习·算法·机器学习·自动驾驶
Full Stack Developme1 小时前
Java DFA算法
java·python·算法
fie88891 小时前
LBP + HOG 特征检测与识别 MATLAB 实现
数据结构·算法·matlab