刷题LeetCode4。寻找两个正序数组的中位数
题目链接:
力扣
题目描述
给定两个大小分别为 m 和 n 的正序(从小到大)数组 nums1 和 nums2。
请你找出并返回这两个正序数组的 中位数 。算法的时间复杂度应该为 O(log (m+n)) 题目分析
常规思路:
1.合并两个数组再排序,时间复杂度O(m+n),空间复杂度O(m+n)
2.归并排序,时间复杂度O(m+n),空间复杂度O(1)
本题解题思路应该如何呢?
根据题目中时间复杂度,可以考虑采用二分查找,这也是本题的难度所在。
假设两个有序数组分别是 A 和 B,两数组的总长度为 totalLength: 两数组总长度(totalLength)为奇数:中位数下标(midIndex)=totalLength/2,中位数=下标midIndex所在数; 两数组总长度(totalLength)为偶数,中位数下标有两个 midIndex1,midIndex2, midIndex1=totalLength/2-1 ,midIndex2=totalLength/2,中位数=(下标midIndex1所在数+下标midIndex2所在数)/2;
注意:midIndex,为两数组合并后的下标,并不是真的将两个数组进行合并,大家要搞清楚这个概念。
这个时候,问题转化为找到数组 A 和 B 中的第 k 大元素(kElement),那怎么找到呢?
可以比较 A[k/2-1] 与B[k/2-1] : A[k/2 1]<=B[k/2 1],则数组A中,下标为 0 至 k/2 1 的元素均小于kElement,可以排除这部分元素; A[k/2 1]>B[k/2 1],则数组B中,下标为 0 至 k/2 1 的元素均小于kElement,可以排除这部分元素;
很容易想到,查找范围缩小了一半,可以在排除后的新数组上继续进行二分查找,并且根据我们排除数的个数,减少 k 的值(因为我们排除的数都不大于第k 小的数)。需要注意以下几种情况:
1.保证数组不越界;
2.如果一个数组为空,说明该数组中的所有元素都被排除,我们可以直接返回另一个数组中第k小的元素;
3.若 k=1,只要返回两个数组首元素的最小值即可。代码实现时间复杂度:O(log (m+n)) 空间复杂度:O(1) public class FindMedianSortedArrays_4 { /** * 常规思路: * 《1》合并两个数组在排序 * 《2》归并排序 * * @param args */ public static void main(String[] args) { int[] num1 = {1, 3}; int[] num2 = {2}; //int[] num1 = {1, 3,4,9}; //int[] num2 = {1,2,3,4,5,6,7,8,9}; FindMedianSortedArrays_4 findMedianSortedArrays_4 = new FindMedianSortedArrays_4(); findMedianSortedArrays_4.findMedianSortedArrays(num1, num2); } /** * 二分查找,巧妙 * 时间复杂度:O(log (m+n)) * 空间复杂度:O(1) * * @param nums1 * @param nums2 * @return */ public double findMedianSortedArrays(int[] nums1, int[] nums2) { int length1 = nums1.length; int length2 = nums2.length; int totalLength = length1 + length2; // 两数组总长度(totalLength)为奇数,中位数下标(midIndex)=totalLength/2,中位数=下标k所在数 if (totalLength % 2 == 1) { System.out.println("两数组总长度(totalLength)为奇数"); int midIndex = totalLength / 2; double median = getKthElement(nums1, nums2, midIndex + 1); System.out.println("median:" + median); return median; } else { // 两数组总长度(totalLength)为偶数,中位数下标有两个 midIndex1,midIndex2, midIndex1=totalLength/2-1 ,midIndex2=totalLength/2, // 中位数=(下标midIndex1所在数+下标midIndex2所在数)/2 System.out.println("两数组总长度(totalLength)为偶数"); int midIndex1 = totalLength / 2 - 1, midIndex2 = totalLength / 2; double median = (getKthElement(nums1, nums2, midIndex1 + 1) + getKthElement(nums1, nums2, midIndex2 + 1)) / 2.0; System.out.println("median:" + median); return median; } } /** * 获取第k小的元素 * * @param nums1 * @param nums2 * @param k * @return */ public int getKthElement(int[] nums1, int[] nums2, int k) { System.out.println("初始k:" + k); int length1 = nums1.length; int length2 = nums2.length; // 用来记录两个数组寻找第k小元素的起始下标 int index1 = 0, index2 = 0; while (true) { // 边界情况,数组1为空,只需要考虑数组2 if (index1 == length1) { return nums2[index2 + k - 1]; } // 边界情况,数组2为空,只需要考虑数组1 if (index2 == length2) { return nums1[index1 + k - 1]; } if (k == 1) { return Math.min(nums1[index1], nums2[index2]); } // 比较 num1[k/2-1] 与 num1[k/2-1] int compareIndex1 = Math.min(index1 + k / 2, length1) - 1; int compare1 = nums1[compareIndex1]; int compareIndex2 = Math.min(index2 + k / 2, length2) - 1; int compare2 = nums2[compareIndex2]; if (compare1 < compare2) { k -= compareIndex1 - index1 + 1; index1 = compareIndex1 + 1; } else { k -= compareIndex2 - index2 + 1; index2 = compareIndex2 + 1; } System.out.println("compare1:" + compare1); System.out.println("compare2:" + compare2); System.out.println("index1:" + index1); System.out.println("index2:" + index2); System.out.println("k:" + k); } } }
注意:while语句中是最核心的部分,也就是二分查找的主要思想。
好了,今天就到这里,感谢各位看官到这里,不如点个关注吧!
东南亚跨境电商平台虾皮Shopee,互联网收租人出海的爱恨纠葛前阵子刷到了虾皮Shopee在抖音上投放的广告,就回想到当年抖音投放在各大平台的广告,这些新生事物的出现都值得我们去了解,因为只有增量才能创造普通人的财富奇迹。这两年为什么会内卷?
python列表推导式和生成器表达式列表推导式和生成器表达式以及字典推导式通常被视为Python中函数式编程的一部分,列表推导允许您使用包含较少代码的for循环创建列表。列表推导式用包围lliforiinrange(
李斌不妥协持续亏损但不涨价,蔚来眼下的关键问题仍然是如何跑得更快。亏损,而且会继续亏一段时间,即使这样,目前蔚来也没有做出涨价的决定。3月25日,蔚来发布了2021年四季度及全年财报,财报显
50变焦1亿主摄256GB跌至1799,骁龙870降1200退场在5G的加速普及下,也催生了很多小众智能手机厂商的成长,比如摩托罗拉。这个智能手机品牌在产品力角度提供了更有性价比更具有美感的外观,抓住了移动电话迅速普及的市场机会,从而走进广大消
零跑T03花8万买L2级自动驾驶?虽然它是一辆买菜车但是在续航里程和动力上并不含糊,甚至有点小电炮的意思,电机最大功率为80kW,最大扭矩158Nm,简单点来说在市区平均速度60kmh左右的工况,秒个法拉域那岂不是
华为p40,小屏轻薄,这是很多手机无法比拟的优势首先,p40小屏轻薄,这是很多手机无法比拟的优势。小屏幕手机选择太少了,这么小的全面屏手机p40是唯一。因为把手机做小太难太难了。我在实体店一个个把手机拿起来,试来试去,还是觉得P
日均赚超4亿元!三大运营商晒成绩单文羊城晚报全媒体记者林曦实习生潘桂怡近日,中国移动发布了2021年年报。据年报显示,中国移动2021年全年营业收入达8482。58亿元,同比增长10。4归母净利润为1159。37亿
玩转SpringBoot之定时任务Scheduled线程池配置序言对于定时任务,在SpringBoot中只需要使用Scheduled这个注解就能够满足需求,它的出现也给我们带了很大的方便,我们只要加上该注解,并且根据需求设置好就可以使用定时任
selenium获取input的value值用selenium获取input中的value值,需要用到一个函数fromseleniumimportwebdriverbrowserwebdriver。Chrome(dBrows
3年10亿元支持技术攻关黑龙江派出科技创新政策豪礼科教资源富集的黑龙江省如何更大力度促进科技创新?近日,黑龙江省政府办公厅印发了黑龙江省进一步推进科技创新发展若干措施(以下简称若干措施)。若干措施突出填补政策空白突出推动科技与经济
电商去中间化是不是一场灾难?忽然有一天,一个神仙大咖在云上画了圈,凭借三寸不烂之舌,拉来了国外资本,爬上了中国电商的最高峰,振臂狂呼,从此让天下没有难做的生意,亿兆百姓在疯狂的价格补贴和秒杀中迷失跳跃跟着大神
300以内买个路由器,有哪些稳定的型号可以推荐?虽然300元价位,但我还是建议选择wifi6路由器,毕竟已经2020年了,wifi6设备加速普及。目前wifi6的300元价位的可选择余地不大。关注度比较高的几款有,小米方面红米a
海康威视躺赚的日子一去不返,安防红利正在消失编辑于斌出品潮起网于见专栏近日,安防巨头海康威视公布了2021年三季度财报,数据显示,公司前三季度主营收入556。29亿元,同比上升32。38归母净利润109。66亿元,同比上升2
不是特斯拉不够硬,而是ARCFOX极狐这次实在太强了不是特斯拉不够硬,而是ARCFOX极狐这次实在太强了不是特斯拉不够硬,而是ARCFOX极狐这次实在太强了前言新能源汽车的逐渐认可促进了这个市场的快速发展,消费者可以选择的品牌和车型
vivoX70Pro硬件配置堆料在线,为何b站UP主却说是天坑?我用的就是X70pro,而且用了一段时间,这个我比较有发言权,缺点确实有,说是天坑就明显过分了,总的来说就是瑕不掩瑜。那些视频都是机器刚发布不久拿来评测的,有bug很正常,但像华为
5G时代基站多少公里建一个?感谢您的阅读!有人说,5G基站只能覆盖几百米,所以可能比4G基站建的更密集。知道4G基站多少公里建一个吗?理论上4G基站的覆盖范围为100KM按照理论值的话,100km建一个4G基
2021双十一量产铝坨坨键盘推荐机械键盘现在也是越来越受到年轻玩家的青睐,不同的机械键盘外观手感功能都有自家的特色,可玩性很高,这一次我们要来看下目前量产的铝合金机械键盘。对于对机械键盘有更高要求的玩家来说,金属
倒计时,华为VRGlass2即将发布,元宇宙或再掀高潮华为VRGlass2被曝或将在本月17号正式发布知名数码博主爆料华为将会在本月中旬发布一款华为全新VRGlass二代,而且还为这款VR眼镜增加了游戏套装。由于前段时间刚好有华为VR
避开首发旗舰机,才是明智选择大家有没有冲首发机器的习惯呢?买首发是对产品和品牌的信任,数码圈里确实是有一部分人喜欢首发,但是我一点都不建议普通消费者冲首发,尤其是旗舰机。旗舰机意味着高溢价,高利润,跳水概率要
马兰士这款珍藏级签名版CD机功放套装直降1W,石渡健会生气么?对于中高端音响玩家来说,马兰士是音响接一个让人非常熟悉的品牌。一直以来,该品牌的器材,始终在中高端的产品定位与范畴中,得到了大家的认可。马兰士创办于1953年,具有悠久丰富的音响元
旧手机除了在家吃灰卖二手,其实还有3种用途很有用处智能手机的快速发展,虽然给我们带来了更为宽广的视野,带来了诸多的便利,但随着手机更新换代的频率加快,旧手机的处理问题已经成为了当下很多人头疼的问题。花了大几千块钱买的,留着吧没什么
为什么那么多人喜欢买苹果手机?那么多是有多少呢?我所了解的喜欢苹果手机的人是有不少,苹果手机在中国也积累了一定的用户和追捧者,但在我知道了苹果手机留有后门之后,我对苹果手机已经没有了热度,介于喜欢和不喜欢之间,