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

【二分查找】

文章目录

  • 1. 二分查找理解
  • 2. 题目练习
    • 2.1 LeetCode 704 二分查找
    • 2.2 LeetCode 35 搜索插入位置
    • 2.3 LeetCode 34 找出开始位置和结束位置。
    • 2.4 LeetCode 69 X的平方根
    • 2.4 LeetCode 367 完全平方数

1. 二分查找理解

使用二分查找的前提是数组是有序的

推荐灵茶山艾府的视频:视频跳转

本文主要考虑的是闭区间的情况
开区间和闭区间最大的差别是初始left和right的取值和while循环的条件;
闭区间:left = 0,right = nums.length-1;
左闭右开:left = 0,right = nums.length;
开区间:left = -1,right = nums.length;
对于left和right的区间变化,时刻记住已经访问过的数组位置不要再次进行判断和访问

import java.util.List;
public class BinarySearch {public static int lower_bound(List<Integer> nums, int target) {int left = 0;int right = nums.size() - 1; // 闭区间 [left, right]while (left <= right) { // 区间不为空int mid = left + (right - left) / 2; // 防止溢出,等同于 (left + right) / 2if (nums.get(mid) < target) {left = mid + 1; // 下一轮搜索区间变为 [mid+1, right]} else {right = mid - 1; // 下一轮搜索区间变为 [left, mid-1]}}return left;// 按照这里的书写情况,是因为当left>right的时候会跳出循环,然而什么时候left会大于right,此时一定是找到了目标值或者数组中不存在这个目标值// 如果是找到了目标值,此时的left就是目标值的位置// 如果是不存在目标值,此时的left就是应该插入的位置}public static int lower_bound(int[] nums, int target) {// 如果存在目标值则输出索引位置,如果不存在目标值则输出-1;int left = 0;int right = nums.length - 1; // 闭区间 [left, right]while (left <= right) { // 区间不为空int mid = left + (right - left) / 2; // 防止溢出if (nums[mid] == target) {return mid;} else if (nums[mid] < target) {left = mid + 1; // 下一轮搜索区间变为 [mid+1, right]} else {right = mid - 1; // 下一轮搜索区间变为 [left, mid-1]}}return -1;}// 如果使用数组而不是List的版本public static int lower_bound1(int[] nums, int target) {int left = 0;int right = nums.length - 1; // 闭区间 [left, right]while (left <= right) { // 区间不为空int mid = left + (right - left) / 2; // 防止溢出if (nums[mid] < target) {left = mid + 1; // 下一轮搜索区间变为 [mid+1, right]} else {right = mid - 1; // 下一轮搜索区间变为 [left, mid-1]}}return left;}// 使用示例public static void main(String[] args) {// 使用List的示例List<Integer> numsList = List.of(1, 2, 4, 4, 5, 6);int target = 8;int result = lower_bound(numsList, target);System.out.println("Lower bound index: " + result); // 输出: 2// 使用数组的示例int[] numsArray = {1, 2, 4, 4, 5, 6};result = lower_bound(numsArray, target);System.out.println("Lower bound index: " + result); // 输出: 2}
}

2. 题目练习

2.1 LeetCode 704 二分查找

LeetCode704

最简单的二分查找的代码

class Solution {public int search(int[] nums, int target) {int left = 0;int right = nums.length-1;while(left<=right){int mid = (left+right)/2;if(nums[mid]==target){return mid;}if(nums[mid]<target){left = mid+1;}else{right = mid-1;}}return -1;}
}

2.2 LeetCode 35 搜索插入位置

题目链接

参考视频中的解法,使得left>right的情况下退出循环,此时的left就是应该插入的位置

class Solution {public int searchInsert(int[] nums, int target) {int left = 0;int right = nums.length-1;while(left<=right){int mid = (left+right)/2;if(nums[mid]==target){return mid;}if(nums[mid]<target){left = mid+1;}else{right = mid-1;}}return left;}
}

2.3 LeetCode 34 找出开始位置和结束位置。

题目链接

start:因为left传输的要么是目标值所在位置,要么是应该插入的位置,所以判断start不存在的情况就是考虑是不是应该插入的位置或者是数组长度,数组长度也是应该插入的位置,但是nums[nums.length]这个数值在数组中不存在,所以start不存的情况需要有两种判断情况
end:同理可得,因为要查找最后一个目标值的位置,相当于寻找 目标值+1 索引位置的前面一个位置,或者是 目标值+1 应该插入的位置的前面一位,比如 [1,2,4,4,8] ,如果我要查找 5 的位置,按照代码会输出 4,即 5 不存在的时候应该插入的位置,而 5 的前面就是最后一个4所在的位置
[1,2,4,4,5,8],如果查找 5 的位置,此时存在 5,输出的left就是 5 在的位置,所以 5 的前一位就是最后一个 4 所在的位置

class Solution {public int lower_bound(int[] nums, int target){int left = 0;int right = nums.length-1;while(left<=right){int mid = (left+right)/2;if(nums[mid]<target){left = mid+1;}else{right = mid-1;}}return left;}public int[] searchRange(int[] nums, int target) {int start = lower_bound(nums,target);if(start == nums.length || nums[start] != target){int[] num = {-1,-1};return num;//不存在start}int end = lower_bound(nums,target+1)-1;int[] res = {start,end};return res;}
}

2.4 LeetCode 69 X的平方根

题目链接

主要是需要理解一下ans = mid这个候选值的情况,因为找的是最大的整数,当left>right 的时候就说明退出循环找到了候选值
而且要注意转变成long型

class Solution {public int mySqrt(int x) {if(x<=1){return x;}int ans = -1;int left = 0;int right = x;// while(left<=right){//     int mid = (left+right)/2;//     if((long)mid*mid == x){//         return mid;//     }else if((long)mid*mid<x){//         ans = mid;//         left = mid+1;//     }else{//         right = mid-1;//     }// }// return ans;while(left<=right){int mid = (left+right)/2;long s_mid = (long)mid*mid;long s1_mid = (long)(mid+1)*(mid+1);if((long)s_mid == x){return mid;}else if((long)s1_mid == x){//其实这个判断可以不考虑,后面会有mid+1return mid+1;}else if(s_mid<x){left = mid+1;// 继续搜索更大的值ans = mid;//记录当前满足条件的候选值,以确保最终返回的是最大的整数 mid}else{right = mid-1;// 搜索更小的值}}return ans;}}

2.4 LeetCode 367 完全平方数

题目链接

class Solution {public boolean isPerfectSquare(int num) {int l=0;int r=num;int ans = -1;while(l<=r){int mid = (l+r)/2;if((long)mid*mid == num){ans = mid;return true;}else if((long)mid*mid<num){l = mid+1;}else{r = mid-1;}}return false;}
}

文章转载自:

http://E5E291zE.rmpfh.cn
http://22XQEAvk.rmpfh.cn
http://yKdqyp6v.rmpfh.cn
http://WQGfkynE.rmpfh.cn
http://VO0LaPtN.rmpfh.cn
http://bbP41EFA.rmpfh.cn
http://qPn8SqFG.rmpfh.cn
http://HGOc79MR.rmpfh.cn
http://uGxaIYgv.rmpfh.cn
http://BJMmBYAq.rmpfh.cn
http://Z2OnW7Ot.rmpfh.cn
http://jP9iM1oV.rmpfh.cn
http://uOim1mCE.rmpfh.cn
http://jv2xEz5h.rmpfh.cn
http://uxDYqKL6.rmpfh.cn
http://CkMxL5O4.rmpfh.cn
http://TgxeIpHZ.rmpfh.cn
http://1oN8PWTz.rmpfh.cn
http://aLZSShuW.rmpfh.cn
http://RPGbigM6.rmpfh.cn
http://EJsAxa0T.rmpfh.cn
http://Z9XhIa23.rmpfh.cn
http://K1MLXsS1.rmpfh.cn
http://dbjkFFNn.rmpfh.cn
http://EfSR1SGr.rmpfh.cn
http://p60KLL4E.rmpfh.cn
http://GamebfRL.rmpfh.cn
http://6uoYpg63.rmpfh.cn
http://9OOcjXyK.rmpfh.cn
http://w0l8UINk.rmpfh.cn
http://www.dtcms.com/a/380779.html

相关文章:

  • 新疆移动中兴B862AV3.1-M2_晨星mso9385_uwe5621ds_优盘免拆卡刷固件包
  • C++:map容器
  • Java内存模型与线程私有共享区域与直接内存的理解
  • MCP专题五、MCP 的未来趋势与展望
  • SIFT特征匹配实战:KNN算法实现指纹认证
  • ETL 不只是数据搬运工:如何实现智能转换与清洗?
  • UDP套接字的使用
  • 【Vue2手录11】Vue脚手架(@vue_cli)详解(环境搭建+项目开发示例)
  • Vue 使用docx-preview,渲染word后,继续其他操作(word中内容相关)的实现
  • [优选算法专题二——NO.16最小覆盖子串]
  • Nginx生产级优化配置全解析和配置原因解析
  • 14自由度汽车动力学模型
  • FS950R08A6P2B 双通道汽车级IGBT模块Infineon英飞凌 电子元器件核心解析
  • 交换机协议栈FRR中使用
  • C++ 二叉搜索树的详解与实现
  • 记录:离线部署
  • python逆向-逆向pyinstaller打包的exe程序反编译获取源代码
  • 最大连续 1 的个数
  • LVS负载均衡群集和LVS+Keepalived群集
  • 嵌入式开发:中断配置全解析
  • 【Vue3】07-利用setup编写vue(2)-setup的语法糖
  • 使用 信号量(Semaphore) 来控制异步任务并发数
  • 1688 商品 API 实战指南:B2B 场景下的合规对接与批量运营方案
  • Qt Bridge for Figma
  • 解决docker配置了镜像源但还会拉取官方镜像源的问题
  • 【JavaEE】网络原理初识
  • 操作系统应用开发(七)mac苹果模拟器——东方仙盟练气期
  • PBI Plus 技术解析:全渠道协同架构下的数据协作效率提升方案​
  • 【C#】三个特殊的 Caller Info Attributes
  • LangChain4j入门学习