【LeetCode笔记】4. 寻找两个正序数组的中位数(Java、二分、递归)
文章目录
- 题目描述
- 思路 & 代码
题目描述
- 算是拖了好久的题目= =,一开始刷的时候没打算直接冲困难
- 不过面试常客了,还是得冲掉,而且不能留下心魔嘛!
- 难点在于实现时间复杂度 O(log(m + n)),显而易见得用二分法
思路 & 代码
- 长度奇偶情况处理:因为偶数要取平均值,所以这边进行了两次函数调用,分别取较小、较大的中位数再取平均(奇数就相当于跑重复了一次)
- 主要思路:基于二分法的基础上进行排除法
- 两数组元素都够的情况,每次舍去 k / 2 个数
- 一方不够的情况,直接指向数组尾,看对比情况舍
- 保证空数组一定是 nums1[ ]
- 证明 & 更多见代码注释
- 注意:k 并非下标
class Solution {/*** 正确性证明:每次去掉的值都是应当去掉的* 因为:答案一定不在数组n去掉范围中,极端情况下也是在数组m范围的尾部* 核心:排除法,不断去掉可去值,并维护k(中位数为第k小数)* ps:其实有效代码只有 20 行= =*/public double findMedianSortedArrays(int[] nums1, int[] nums2) {int n = nums1.length;int m = nums2.length;// +1 +2:k 不是下标,比如 k = 1,指第一个,也就是 index + k - 1// left & right 是为了奇偶// 奇数情况 left == right// 偶数情况 left == right - 1int left = (n + m + 1) / 2;int right = (n + m + 2) / 2;// 奇数情况:两次一样的过程// 偶数情况:中间俩个值的平均值return (getKth(nums1, 0, n - 1, nums2, 0, m - 1, left)+ getKth(nums1, 0, n - 1, nums2, 0, m - 1, right)) / 2.0;}int getKth(int[] nums1, int start1, int end1, int[] nums2, int start2, int end2, int k){int len1 = end1 - start1 + 1;int len2 = end2 - start2 + 1;// 保证空数组一定是 nums1[]if(len1 > len2){return getKth(nums2, start2, end2, nums1, start1, end1, k);}// 出现空数组,直接化成求一数组第k小数的情况if(len1 == 0){return nums2[start2 + k - 1];}// 找到最后的情况,直接返回两数组当前最小值if(k == 1){return Math.min(nums1[start1], nums2[start2]);}// 指向第k/2小的位置 or 指向尾部int i = start1 + Math.min(len1, k / 2) - 1;int j = start2 + Math.min(len2, k / 2) - 1;// 舍去值的数量不一定相等(指向尾部情况)// 舍nums2的情况if(nums1[i] > nums2[j]){return getKth(nums1, start1, end1, nums2, j + 1, end2, k - (j - start2 + 1));}// 舍nums1的情况else{return getKth(nums1, i + 1, end1, nums2, start2, end2, k - (i - start1 + 1));}}}
- 无注释版
class Solution {public double findMedianSortedArrays(int[] nums1, int[] nums2) {int mid1 = (nums1.length + nums2.length + 1) / 2;int mid2 = (nums1.length + nums2.length + 2) / 2;return (getMid(nums1, 0, nums1.length - 1, nums2, 0, nums2.length - 1, mid1) + getMid(nums1, 0, nums1.length - 1, nums2, 0, nums2.length - 1, mid2)) / 2.0;}public int getMid(int[] nums1, int start1, int end1, int[] nums2, int start2, int end2, int k) {int len1 = end1 - start1 + 1;int len2 = end2 - start2 + 1;if(len2 < len1) {return getMid(nums2, start2, end2, nums1, start1, end1, k);}if(len1 == 0) {return nums2[start2 + k - 1];}if(k == 1) {return Math.min(nums1[start1], nums2[start2]);}int index1 = start1 + Math.min(len1, k / 2) - 1;int index2 = start2 + Math.min(len2, k / 2) - 1;if(nums1[index1] < nums2[index2]) {return getMid(nums1, index1 + 1, end1, nums2, start2, end2, k - (index1 - start1 + 1));}else {return getMid(nums1, start1, end1, nums2, index2 + 1, end2, k - (index2 - start2 + 1));}}
}
【LeetCode笔记】4. 寻找两个正序数组的中位数(Java、二分、递归)相关推荐
- 【LeetCode】4.寻找两个正序数组的中位数
4.寻找两个正序数组的中位数 一.问题描述 给定两个大小分别为 m 和 n 的正序(从小到大)数组 nums1 和 nums2.请你找出并返回这两个正序数组的 中位数 . 二.问题简化 所谓中位数,就 ...
- 【LeetCode】【HOT】4. 寻找两个正序数组的中位数(二分查找)
[LeetCode][HOT]4. 寻找两个正序数组的中位数 文章目录 [LeetCode][HOT]4. 寻找两个正序数组的中位数 package hot;public class Solution ...
- java打乱一组正序数字,Leetcode︱4.Median of Two Sorted Arrays寻找两个正序数组的中位数.java...
题目 给定两个大小分别为 m 和 n 的正序(从小到大)数组 nums1 和 nums2.请你找出并返回这两个正序数组的 中位数 . 示例 : 输入:nums1 = [1,3], nums2 = [2 ...
- 40.寻找两个正序数组的中位数(二分排除法)
== case1==:此时k/2都比数组的有效长度小 case2:数组长度小于k/2 case3:查找的只剩下一个数组 注意:偶数长度的情况,可能出现0.5的小数位数,注意使用乘的0.5自动转换为do ...
- [二分搜索|快速选择] leetcode 4 寻找两个正序数组的中位数
[二分搜索|快速选择] leetcode 4 寻找两个正序数组的中位数 1.题目 题目链接 给定两个大小为 m 和 n 的正序(从小到大)数组 nums1 和 nums2.请你找出并返回这两个正序数组 ...
- LeetCode 4 寻找两个正序数组的中位数
https://leetcode-cn.com/problems/median-of-two-sorted-arra 解决方案 Go 版本 func findMedianSortedArrays(nu ...
- 2022-6-13 全O(1)的数据结构,两数相加,无重复字符的最长子串,寻找两个正序数组的中位数,盛最多水的容器,......
1. 全 O(1) 的数据结构 Design a data structure to store the strings' count with the ability to return the s ...
- 寻找两个正序数组的中位数
寻找两个正序数组的中位数 时隔许久,我又回来了. 题目:给定两个大小分别为m和n的正序(从小到大)数组nums1和nums2.请你找出并返回这两个正序数组的中位数. 要求算法的时间复杂度为O(log( ...
- LeetCode 04寻找两个正序数组的中位数(困难)二分法
题目描述: 呕心沥血的一个题解,点赞关注收藏,一键三联,一起加入我们打卡! 题目描述: 给定两个大小为 m 和 n 的正序(从小到大)数组 nums1 和 nums2. 请你找出这两个正序数组的中位数 ...
- LeetCode - 4. 寻找两个正序数组的中位数
题目来源:力扣(LeetCode) 链接:https://leetcode-cn.com/problems/median-of-two-sorted-arrays 题目描述 给定两个大小为 m 和 n ...
最新文章
- 敏捷团队如何通过Leangoo领歌迭代看板进行迭代规划和任务协同
- Nat Rev Genet发表房刚组细菌表观组综述论文
- Gabor滤波小结整理
- 安装ESXI 5.1
- SAP Spartacus HTTP请求url里的语言和货币参数是如何加上去的
- 奔跑吧兄弟变成机器人是哪一期_强竞技的《奔跑吧3》蜕变为“生活服务类综艺”,你还愿意看吗?...
- x·dy+y²·sinx·dx=0
- MYSQL GDB 崩溃调试
- IDEA怎么导入一个maven项目
- 华为交换机开启ftp服务,上传和下载文件,get和put操作实例
- oracle实时备份归档日志实现异机恢复丢失数据最小化
- 澳洲java待遇_2018年澳洲IT薪资一览,最新IT薪水Salary,给学IT的同学打一针鸡血...
- 获取iOS设备的型号(iPhone4,iphone5,iPhone5s......)
- C++编程第一步:判断一个数字是不是整数
- 华为云、百度云 群控系统开发流程
- java switch是什么意思_java switch语句详解
- 如何实现表格行列冻结
- 澳洲八大的IB(International Baccalaureate)成绩录取要求
- org.gradle.api.resources.ResourceException: Could not get resource ‘https://xxx.xxx/xxx.pom
- 源码之 Retrofit