搜索插入位置(035)

class Solution {
public int searchInsert(int[] nums, int target) {
int n = nums.length;
int lef = -1;
int rig = n;
while(lef+1 < rig){
int mid = (lef + rig) / 2;
if (nums[mid] < target){
lef = mid;
}else rig = mid;
}
return rig;
}
}
  • 分析

基础二分

搜索二维矩阵(074)

class Solution {
public boolean searchMatrix(int[][] matrix, int target) {
int m = matrix.length;
int n = matrix[0].length;
int lef = -1;
int rig = m*n;
while (lef+1 < rig){
int mid = (lef + rig) / 2;
int x = matrix[mid/n][mid%n]; if (x < target) lef = mid;
else if (x > target) rig = mid;
else return true;
}
return false;
}
}
  • 分析

把每一个row 横向相连, 作二分

在排序数组中查找元素的第一个和最后一个位置(034)

class Solution {
public int[] searchRange(int[] nums, int target) { int start = searchLower(-1 ,nums, target);
if (start == nums.length || nums[start] != target) return new int[]{-1,-1}; int end = searchLower(start, nums, target+1) -1;
return new int[] {start, end};
} private int searchLower(int lef, int[] nums, int target){ int rig = nums.length; while (lef + 1 < rig){
int mid = (lef + rig) / 2;
if (nums[mid] < target) lef = mid;
else rig = mid;
} return rig;
}
}
  • 分析

通过两次二分 查找 target 和target+1的起始位置, 确定target的范围

搜索旋转排序数组(033)

class Solution {
public int search(int[] nums, int target) {
int n = nums.length -1;
int lef = -1;
int rig = n;
while (lef + 1< rig){
int mid = (lef + rig) / 2;
if (check(nums, target, mid)){ //target在mid右侧
lef = mid;
}else rig = mid;
}
return nums[rig] == target ? rig : -1;
} private boolean check(int[] nums, int target, int idx){
int x = nums[idx];
int end = nums[nums.length-1]; if (x < end){
return x < target && target <= end; // mid在小端 且比target小
}
// mid在大端 且< target在小端 || target > mid >
return x < target || target <= end;
}
}
  • 分析

通过mid和end值的对比, 确定mid的位置<旋转小端, 旋转大端>

根据 mid的位置再分类讨论

寻找旋转排序数组的最小值(153)

class Solution {
public int findMin(int[] nums) {
int n = nums.length;
int lef = -1;
int rig = n;
while (lef+1 < rig){
int mid = (lef + rig) / 2;
if(nums[mid] > nums[n-1]){ // 在右侧
lef = mid;
}else rig = mid;
}
return nums[rig];
}
}
  • 分析

判断 mid 在<大端, 小端> →<右移, 左移>

  • 感悟

二分用来查找数据的拐点, 以<条件>作check()

寻找两个正序数组的中位数(004)

这题给我写晕厥了

class Solution {
public double findMedianSortedArrays(int[] nums1, int[] nums2) {
if (nums1.length > nums2.length){
return findMedianSortedArrays(nums2, nums1);
} int m = nums1.length;
int n = nums2.length; int lef = -1;
int rig = m; while (lef+1 < rig){
int mid_nums1 = (lef+rig) / 2;
int mid_nums2 = (m+n+1) / 2 - (mid_nums1+1) -1;
if(nums1[mid_nums1] - nums2[mid_nums2+1] <= 0){
lef = mid_nums1;
}else rig = mid_nums1;
} int idx_nums1 = lef;
int idx_nums2 = (m+n+1)/2 - (lef+1) - 1;
int lef_max_nums1 = idx_nums1 >= 0 ? nums1[idx_nums1] : Integer.MIN_VALUE;
int lef_max_nums2 = idx_nums2 >= 0 ? nums2[idx_nums2] : Integer.MIN_VALUE;
int rig_min_nums1 = idx_nums1 + 1 < m ? nums1[idx_nums1+1] : Integer.MAX_VALUE;
int rig_min_nums2 = idx_nums2 + 1 < n ? nums2[idx_nums2+1] : Integer.MAX_VALUE; int max = Math.max(lef_max_nums1, lef_max_nums2);
int min = Math.min(rig_min_nums1, rig_min_nums2); return (m+n)%2 != 0 ? max : (max+min) / 2.0;
}
}
  • 分析

我们取两数组<红>作为总数据集<中位数左侧>的小端, <蓝>作为总数据集<中位数右侧>的大端

接下来我们通过二分找拐点if(nums1[mid_nums1] - nums2[mid_nums2+1] <= 0)

如果从<红>中取<蓝>对<红>产生正反馈(变大) 取 rig = mid

产生负反馈(变小或不变) 取 lef = mid

hot100之二分查找的更多相关文章

  1. jvascript 顺序查找和二分查找法

    第一种:顺序查找法 中心思想:和数组中的值逐个比对! /* * 参数说明: * array:传入数组 * findVal:传入需要查找的数 */ function Orderseach(array,f ...

  2. Java实现的二分查找算法

    二分查找又称折半查找,它是一种效率较高的查找方法. 折半查找的算法思想是将数列按有序化(递增或递减)排列,查找过程中采用跳跃式方式查找,即先以有序数列的中点位置为比较对象,如果要找的元素值小 于该中点 ...

  3. 从一个NOI题目再学习二分查找。

    二分法的基本思路是对一个有序序列(递增递减都可以)查找时,测试一个中间下标处的值,若值比期待值小,则在更大的一侧进行查找(反之亦然),查找时再次二分.这比顺序访问要少很多访问量,效率很高. 设:low ...

  4. java实现二分查找

    /** * 二分查找 * @param a * @param n * @param value * @return * @date 2016-10-8 * @author shaobn */ publ ...

  5. 最新IP地址数据库 二分逼近&二分查找 高效解析800万大数据之区域分布

    最新IP地址数据库  来自 qqzeng.com 利用二分逼近法(bisection method) ,每秒300多万, 比较高效! 原来的顺序查找算法 效率比较低 readonly string i ...

  6. c#-二分查找-算法

    折半搜索,也称二分查找算法.二分搜索,是一种在有序数组中查找某一特定元素的搜索算法. A 搜素过程从数组的中间元素开始,如果中间元素正好是要查找的元素,则搜素过程结束: B 如果某一特定元素大于或者小 ...

  7. 【Python】二分查找算法

    二分查找:在一段数字内,找到中间值,判断要找的值和中间值大小的比较.如果中间值大一些,则在中间值的左侧区域继续按照上述方式查找.如果中间值小一些,则在中间值的右侧区域继续按照上述方式查找.直到找到我们 ...

  8. PHP实现文本快速查找 - 二分查找

    PHP实现文本快速查找 - 二分查找法 起因 先说说事情的起因,最近在分析数据时经常遇到一种场景,代码需要频繁的读某一张数据库的表,比如根据地区ID获取地区名称.根据网站分类ID获取分类名称.根据关键 ...

  9. java二分查找举例讨论

    最近做笔试题有这么一个关于二分查找的例子. 给一个有序数组,和一个查找目标,用二分查找找出目标所在index,如果不存在,则返回-1-(其应该出现的位置),比如在0,6,9,15,18中找15,返回3 ...

  10. JAVA源码走读(二)二分查找与Arrays类

    给数组赋值:通过fill方法. 对数组排序:通过sort方法,按升序.比较数组:通过equals方法比较数组中元素值是否相等.查找数组元素:通过binarySearch方法能对排序好的数组进行二分查找 ...

随机推荐

  1. Docker部署RocketMQ(JDK11)

    说起微服务,不谈容器,不谈云,那还谈个啥?容器中又以Docker最为流行,那么我们今天就来实践下容器化微服务,然后顺带解决下各种疑难杂症. 环境: Idea2019.03/Gradle6.0.1/JD ...

  2. Hangfire Redis 实现秒级定时任务、使用 CQRS 实现动态执行代码

    目录 定时任务需求 核心逻辑 使用 Redis 实现秒级定时任务 第一步 第二步 第三步 第四步 业务服务实现动态代码 第一步 第二步 第三步 第四步 第五步 最后 定时任务需求 本文示例项目仓库:w ...

  3. 查询相册更加mysql 查询

    接到一个项目项目案例相册是这种结构 大佬建议 sql 查询 groip 进行时间统计今天 field根据mysql 时间查询进行统计 今天多少条 新增多少条相册 计算天数 $lists = Album ...

  4. VUE环境搭建(一)——NPM安装

    VUE环境搭建--NPM安装 npm: Nodejs下的包管理器. webpack: 它主要的用途是通过CommonJS的语法把所有浏览器端需要发布的静态资源做相应的准备,比如资源的合并和打包. vu ...

  5. DevEco Studio AI辅助开发工具两大升级功能 鸿蒙应用开发效率再提升

    随着搭载HarmonyOS 5的Pura X发布,鸿蒙生态进入快车道,各应用正在加速适配开发,越来越多开发者加入到鸿蒙应用开发浪潮中.为提升鸿蒙应用开发效率,华为前不久上线了首款开发HarmonyOS ...

  6. 初见 cmake

    初见 cmake cmake 是自动生成构建系统的一个工具.cmake 本身不是构建系统,它是一个生成构建系统的工具.或者说 cmake 不是一个构建工具,是一个能根据平台生成对应平台构建系统配置的构 ...

  7. 词库过大导致的Redis超时问题-RedisCommandTimeoutException

    问题 Redis缓存超时问题 报错内容 redis io.lettuce.core.RedisCommandTimeoutException: Command timed out after 10 s ...

  8. 【Java持久层技术演进全解析】从JDBC到MyBatis再到MyBatis-Plus

    从JDBC到MyBatis再到MyBatis-Plus:Java持久层技术演进全解析 引言 在Java企业级应用开发中,数据持久化是核心需求之一.本文将系统性地介绍Java持久层技术的演进过程,从最基 ...

  9. 剖析 Vue:最适合小白入手的前端框架

    @charset "UTF-8"; .markdown-body { line-height: 1.75; font-weight: 400; font-size: 15px; o ...

  10. 网络编程:C10K问题

    C10K问题 C10K问题就是如何一台物理机上同时服务10000个用户?C代表并发,10K就是10000 C10K 问题是由一个叫 Dan Kegel 的工程师提出并总结归纳的,你可以通过访问http ...