Plantre Plantre
首页
  • 算法

    • 查找
    • 排序
  • 力扣

    • 排序
技术
硬件
逆向
  • 前端文章

    • HTML
    • CSS
    • JavaScript
  • 技术

    • 技术文档
    • GitHub技巧
    • Nodejs
    • 博客搭建
  • 学习笔记

    • 《JavaScript教程》
    • 《JavaScript高级程序设计》
    • 《ES6 教程》
    • 《Vue》
    • 《React》
    • 《TypeScript 从零实现 axios》
    • 《Git》
    • TypeScript
    • JS设计模式总结
  • 学习
  • 面试
  • 心情杂货
  • 实用技巧
  • 友情链接
关于
收藏
  • 分类
  • 标签
  • 归档
GitHub (opens new window)

plantre

一个后端开发者
首页
  • 算法

    • 查找
    • 排序
  • 力扣

    • 排序
技术
硬件
逆向
  • 前端文章

    • HTML
    • CSS
    • JavaScript
  • 技术

    • 技术文档
    • GitHub技巧
    • Nodejs
    • 博客搭建
  • 学习笔记

    • 《JavaScript教程》
    • 《JavaScript高级程序设计》
    • 《ES6 教程》
    • 《Vue》
    • 《React》
    • 《TypeScript 从零实现 axios》
    • 《Git》
    • TypeScript
    • JS设计模式总结
  • 学习
  • 面试
  • 心情杂货
  • 实用技巧
  • 友情链接
关于
收藏
  • 分类
  • 标签
  • 归档
GitHub (opens new window)
  • 计算机组成原理

  • 操作系统

  • 计算机网络

  • 设计模式

  • Java

  • Spring

  • SpringCloud

  • MySQL

  • Redis

  • 分布式

  • Zookeeper

  • Dubbo

  • Kafka

  • 数据结构

  • 算法

  • OJ

    • 自定义
    • 排序
    • 位运算
    • 二分查找
      • 递归
      • 双指针(逆向,快慢)
      • 滑动窗口
      • 辅助栈
      • 贪心
      • 回溯
      • 动态规划
      • 二叉树
      • DFS
      • 拼接&拆分
      • 模拟
      • 工业实现原理
      • 数学
      • 字符串
    • 从道家哲学看计算机?
    • 后端
    • OJ
    plantre
    2025-06-11
    目录

    二分查找

    # 34. 在排序数组中查找元素的第一个和最后一个位置 - 力扣(LeetCode) (opens new window)

    class Solution {
        public int[] searchRange(int[] nums, int target) {
            return new int[]{left_bound(nums,target),right_bound(nums,target)};
        }
        //常规
        int binary_search(int[] nums,int target){
            int left = 0, right = nums.length - 1;
            while (left <= right) {
                int mid = left + (right - left) / 2;
                if (nums[mid] < target) {
                    left = mid + 1;
                } else if (nums[mid] > target) {
                    right = mid - 1;
                } else if (nums[mid] == target) {
                    //直接返回
                    right = mid;
                }
            }
            //直接返回
            return -1;
        }
        //搜索左边界
        int left_bound(int[] nums,int target){
            int left = 0, right = nums.length - 1;
            while (left <= right) {
                int mid = left + (right - left) / 2;
                if (nums[mid] < target) {
                    left = mid + 1;
                } else if (nums[mid] > target) {
                    right = mid - 1;
                } else if (nums[mid] == target) {
                    //别返回,锁定左侧边界
                    right = mid - 1;
                }
            }
            //判断 target 是否存在于nums中
            if (left < 0 || left >= nums.length) {
                return -1;
            }
            //判断一下nums[left]是不是target
            return nums[left] == target ? left : -1;
        }
        //搜索右边界
        int right_bound(int[] nums,int target){
            int left = 0,right = nums.length - 1;
            while (left <= right) {
                int mid = left + (right - left) / 2;
                if (nums[mid] < target){
                    left = mid + 1;
                } else if (nums[mid] > target) {
                    right = mid - 1;
                } else if (nums[mid] == target) {
                    //别返回,锁定右侧边界
                    left = mid + 1;
                }
            }
            //由于while的结束条件是right == left - 1,且现在在求右边界
            //所以用right代替 left - 1更好记住
            if (right < 0 || right >= nums.length) {
                return -1;
            }     
            return nums[right] == target ? right : -1;
        }
    }
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64

    # 704. 二分查找 - 力扣(LeetCode) (opens new window)

    class Solution {
        public int search(int[] nums, int target) {
            int left = 0, right = nums.length - 1;
            while (left <= right){
                int mid = (right - left) / 2 + left;
                int num = nums[mid];
                if(num == target){
                    return mid;
                } else if (num > target){
                    right = mid - 1;
                } else {
                    left = mid + 1;
                }
            }
            return -1;
        }
    }
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17

    # 162. 寻找峰值 - 力扣(LeetCode) (opens new window)

    left < right 保证循环结束时 left == right,此时仅剩一个元素,直接返回该位置即为峰值索引

    若用 left <= right:当 left == right 时循环仍会执行,但此时 mid = left,后续比较 nums[mid] 与 nums[mid + 1] 可能导致 数组越界(因 mid + 1 可能超出边界)

    class Solution {
        public int findPeakElement(int[] nums) {
            int left = 0, right = nums.length - 1;
            while (left < right) {
                int mid = left + (right - left) / 2;
                if (nums[mid] < nums[mid + 1]) {
                    left = mid + 1;
                } else {
                    right = mid;
                }
            }
            return left;
        }
    }
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14

    # 35. 搜索插入位置 - 力扣(LeetCode) (opens new window)

    class Solution {
        public int searchInsert(int[] nums, int target) {
            int left = 0, right =  nums.length - 1;
            while (left <= right) {
                int mid = ((right - left) >> 1) + left;
                if (nums[mid] == target) {
                    return mid;
                } else if (nums[mid] < target) {
                    left = mid + 1;
                } else {
                    right = mid - 1;
                }
            }
            return left;
        }
    }
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16

    # 33. 搜索旋转排序数组 - 力扣(LeetCode) (opens new window)

    class Solution {
        public int search(int[] nums, int target) {
            int left = 0, right = nums.length-1;
            while (left <= right) {
                int mid = left + (right - left) / 2;
                if (nums[mid] == target) {
                    return mid;
                }
                if (nums[mid] >= nums[left]){
                    if (nums[left] <= target && target < nums[mid]) {
                        right = mid - 1;
                    } else {
                        left = mid + 1;
                    }
                } else {
                    if (nums[mid] < target && target <= nums[right]) {
                        left = mid + 1;
                    } else {
                        right = mid - 1;
                    }
                }
            }
            return -1;
        }
    }
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    编辑 (opens new window)
    上次更新: 2025/07/16, 10:21:39
    位运算
    递归

    ← 位运算 递归→

    最近更新
    01
    加油鸭
    07-30
    02
    要点总结
    07-28
    03
    字符串
    07-15
    更多文章>
    Theme by Vdoing | Copyright © 2025-2025 plantre | MIT License
    • 跟随系统
    • 浅色模式
    • 深色模式
    • 阅读模式