【LeetCode】4. 寻找两个正序数组的中位数

前言

寻找两个正序数组的中位数
给定两个大小分别为 m 和 n 的正序(从小到大)数组 nums1 和 nums2。请你找出并返回这两个正序数组的 中位数 。

算法的时间复杂度应该为 O(log (m+n)) 。

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/median-of-two-sorted-arrays
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

/**
 * 解析:
 * 找a和b两个有序数组中第K小,就是在a中找某个位置i,在b中找某个位置j,求得第k位置的k小值
 * 数组a,长度m,位置i,0<=i<=m
 * 数组b,长度n,位置j,0<=j<=n
 * m+n是奇数,k=(m+n)/2,k小就是k位置对应的值
 * m+n是偶数,k=(m+n)/2和k=(m+n)/2 + 1,k小就是这2个k位置的平均值
 * 其满足条件为 i + j = k,且 a[i - 1] <= b[j] && b[j - 1] <= a[i],
 * 则k小 = max(a[i - 1], b[j - 1])
 * 由于0<=j<=n,j=k-i
 * 则 0<=k-i<=n,同时乘以-1,得-n<=i-k<=0,同时加k得 k-n<=i<=k
 * k-n<=i<=k && 0<=i<=m,得 max(0, k-n)<=i<=min(k, m)
 * 先求得位置i,即可求得位置j,最后求得k小= max(a[i - 1], b[j - 1])
 */

/**
 * @param {number[]} nums1
 * @param {number[]} nums2
 * @return {number}
 */
var findMedianSortedArrays = function (nums1, nums2) {
 const len = nums1.length + nums2.length
 if (len & 1) {
   return findK(nums1, nums2, Math.ceil(len / 2))
 } else {
   return (findK(nums1, nums2, len / 2) + findK(nums1, nums2, len / 2 + 1)) / 2
 }
}

var findK = function(nums1, nums2, k) {
 let m = nums1.length, n = nums2.length, i = 0, j = 0
 let left = Math.max(0, k - n), right = Math.min(k, m)
 while (left < right) {
   // mid就是i
   const mid = Math.floor(left + (right - left) / 2)
   // 即b[j - 1] > a[i]
   if (nums2[k - mid - 1] > nums1[mid]) {
     left = mid + 1
   } else {
     right = mid
   }
 }
 // right就是求得的i,由于max(0, k-n)<=i<=min(k, m),k小=max(nums1[right - 1], nums2[k - right - 1])
 let leftmax = right === 0 ? Number.MIN_SAFE_INTEGER : nums1[right - 1]
 let rightmax = right === k ? Number.MIN_SAFE_INTEGER : nums2[k - right - 1]
 return Math.max(leftmax, rightmax);
};

总结

二分查找寻找具体数,对题目进行解析。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值