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

二分查找----6.寻找两个正序数组的中位数

4. 寻找两个正序数组的中位数 - 力扣(LeetCode)

/**

        给定两个升序数组,将两数组看作整体寻找中位数;要求时间复杂度O(log (m+n)),则不能直接合并数组.

        大致解法:

                (暂时不考虑偶数情况)

                如果数组合并,那么在nums1与nums2中必然存在两个分割点,

                nums1的前i个元素与nums2的前j个元素构成合并后的左半区(包括中位数),

                中位数即为nums1前i个元素与nums2前j个元素中较大的那个,且i + j = (m + n + 1) / 2(兼容奇偶)

                同时满足左半区的最大值小于右半区的最小值

        左半区元素个数:

                i + j = (m + n + 1) / 2 ---> 左右半区元素个数相等(奇);左比右多1(偶);nums1取i个、nums2取j个

        分割合法性:

                左半区最大元素小于右半区最小元素

                nums1[i - 1] < nums1[i] (必然满足)

                nums1[i - 1] < nums2[j]

                nums2[j - 1] < nums2[j] (必然满足)

                nums2[j - 1] < nums1[i]  

        核心:

                那么中位数寻找就转变为了搜寻满足条件的i或j; i + j = (m + n + 1) / 2

                只需搜寻一个即可,哪个数组更短搜寻哪个即可

*/

class Solution {/**给定两个升序数组,将两数组看作整体寻找中位数;要求时间复杂度O(log (m+n)),则不能直接合并数组.大致解法:(暂时不考虑偶数情况)如果数组合并,那么在nums1与nums2中必然存在两个分割点,nums1的前i个元素与nums2的前j个元素构成合并后的左半区(包括中位数),中位数即为nums1前i个元素与nums2前j个元素中较大的那个,且i + j = (m + n + 1) / 2(兼容奇偶)同时满足左半区的最大值小于右半区的最小值左半区元素个数:i + j = (m + n + 1) / 2 ---> 左右半区元素个数相等(奇);左比右多1(偶);nums1取i个、nums2取j个分割合法性:左半区最大元素小于右半区最小元素nums1[i - 1] < nums1[i] (必然满足)nums1[i - 1] < nums2[j]nums2[j - 1] < nums2[j] (必然满足)nums2[j - 1] < nums1[i]   核心:那么中位数寻找就转变为了搜寻满足条件的i或j; i + j = (m + n + 1) / 2只需搜寻一个即可,哪个数组更短搜寻哪个即可*/public double findMedianSortedArrays(int[] nums1, int[] nums2) {//保证nums1是较短的数组if(nums1.length > nums2.length) {int[] temp = nums1;nums1 = nums2;nums2 = temp;}int m = nums1.length, n = nums2.length;//双指针置于nums1有效部分两端int left = 0, right = m; while(left <= right) {int sumLeft = (m + n + 1) >>> 1; //左半区元素总数 i + jint i = (left + right) >>> 1; //二分查找搜寻满足条件的i(nums1中选取的元素数)int j = sumLeft - i; // j(nums2中选取的元素数)//边界处理,左半区完全在nums1或左半区完全在nums2;以及nums1或nums2全部需要int nums1Left = (i == 0) ? Integer.MIN_VALUE : nums1[i - 1]; //左半区完全在nums2int nums1Right = (i == m) ? Integer.MAX_VALUE : nums1[i]; //nums1全部需要int nums2Left = (j == 0) ? Integer.MIN_VALUE : nums2[j - 1]; //左半区完全在nums1int nums2Right = (j == n) ? Integer.MAX_VALUE : nums2[j]; //nums2全部需要//分割合法性/**  需进行边界处理,不可直接判断if(nums1[i - 1] <= nums2[j] && nums2[j - 1] <= nums1[i]) {*/if(nums1Left <= nums2Right && nums2Left <= nums1Right) {if((m + n) % 2 == 1) { //奇数,返回左半区最大值即可return Math.max(nums1Left, nums2Left);} else { //偶数,分割点左侧最大值以及分割点右侧最小值的平均值return (Math.max(nums1Left,nums2Left) + Math.min(nums1Right,nums2Right)) / 2.0;}} //分割不合法,分情况进行调整else {if( nums1Left > nums2Right) { //nums1选取元素数过大right = i - 1; //减少nums1可选元素} else if(nums2Left > nums1Right) { //nums2选取元素数过大left = i + 1; //增多nums1可选元素、即减少nums2可选元素 (总数固定,此消彼长)}}}return -1;}  }

http://www.lryc.cn/news/599722.html

相关文章:

  • 基于深度学习的图像分类:使用Vision Transformer(ViT)实现高效分类
  • Lakehouse x AI ,打造智能 BI 新体验
  • 认识一下Qlib的158因子特征
  • Gitee Test:国产软件测试平台如何筑牢关键领域数字安全屏障
  • PI 思维升级 PI设计的典范转移:从阻抗思维到谐振控制
  • 主要分布在背侧海马体(dHPC)CA1区域(dCA1)的时空联合细胞对NLP中的深层语义分析的积极影响和启示
  • 杂谈:前端开发中的常见问题
  • 【机器学习之推荐算法】基于矩阵分解和损失函数梯度下降的协同过滤算法实现
  • 验证 GitHub Pages 的自定义域(Windows)
  • Power Compiler:漏电功耗、内部功耗、切换功耗及其计算方式(NLPM)
  • 【通识】如何看电路图
  • ATH12K 驱动框架分析
  • Docker容器技术:从入门到精通
  • J2EE模式---数据访问对象模式
  • 电科金仓新一代数据库一体机:以 “云数据库 - AI 版” 引领 AI 时代数据库变革
  • C++中的反向迭代器
  • Linux下使用VSCode配置GCC环境与调试指南
  • 基于单片机的楼宇门禁系统的设计与实现
  • 电商数据采集API与爬虫技术结合的全网比价方案
  • 目前市面上arm64-v8a、armeabi-v7a设备的市占率有多少?为什么x86架构的手机越来越少?
  • Python 数据分析(一):NumPy 基础知识
  • 【硬件-笔试面试题】硬件/电子工程师,笔试面试题-26,(知识点:硬件电路的调试方法:信号追踪,替换,分段调试)
  • 支付宝小程序 DAU 提升策略:激发每日用户活力
  • 破局与重构:King’s LIMS 引领电子行业实验室智能化转型
  • Logstash 多表增量同步 MySQL 到 Elasticsearch:支持逻辑删除与热加载,Docker 快速部署实战
  • Qt 状态机框架:复杂交互逻辑的处理
  • uniapp之微信小程序标题对其右上角按钮胶囊
  • Vue3中的标签 ref 与 defineExpose:模板引用与组件暴露
  • 【Linux网络编程】传输层协议 - TCP
  • 图论水题日记