You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
(j ==0or i == m orB[j-1] <=A[i]) and (i ==0or j == n orA[i-1] <=B[j])
因此在二分查找的循环中,只需要判断以下条件:
<a> (j ==0or i == m orB[j-1] <=A[i]) and
(i ==0or j = n orA[i-1] <=B[j])
找到需要的 i 值
<b> j >0and i < m andB[j -1] >A[i]
i 太小,需要增加,但不能超过 m
<c> i >0and j < n andA[i -1] >B[j]
i 太大,需要较少,但要大于 0, 等于0 则进行 a 条件判断
上述条件中, 因为 i < m, j = (m+n+1)/2 - i > (m+n+1)/2 - m >= (2*m+1)/2 - m >= 0, 因此可以不用判断 j > 0; c 条件同上;
上述三个条件互斥, 因此先判断后续两个条件即可。
Accepted
Runtime: 240 ms, faster than 100.00% of Kotlin online submissions for Median of Two Sorted Arrays.
Memory Usage: 44.1 MB, less than 66.67% of Kotlin online submissions for Median of Two Sorted Arrays.
importorg.testng.annotations.TestfunfindMedianSortedArrays(nums1:IntArray, nums2:IntArray): Double {
val m = nums1.size
val n = nums2.size
if (m > n) {
return findMedianSortedArrays(nums2, nums1)
}
var low =0var high = m
while (low <= high) {
// 针对 nums1 进行 二分查找val i = low + (high - low).shr(1)
val j = (m + n).shr(1) - i
if (i < m && nums2[j -1] > nums1[i]) {
low = i +1
} elseif (i >0&& nums1[i -1] > nums2[j]) {
high = i -1
} else {
// 找到想要的 i 值println(i)
var minRight =0
minRight =when {
i == m -> nums2[j]
j == n -> nums1[i]
else->Math.min(nums1[i], nums2[j])
}
if ((m + n) %2==1) {
return minRight *1.0
}
var maxLeft =0
maxLeft =when {
i ==0-> nums2[j -1]
j ==0-> nums1[i -1]
else->Math.max(nums1[i -1], nums2[j -1])
}
return0.5* (maxLeft + minRight)
// var maxLeft = 0// maxLeft = when {// i == 0 -> nums2[j - 1]// j == 0 -> nums1[i - 1]// else -> Math.max(nums1[i - 1], nums2[j - 1])// }// if ((m + n) % 2 == 1) {// return maxLeft * 1.0// }// // 偶数逻辑// var minRight = 0// minRight = when {// i == m -> nums2[j]// j == n -> nums1[i]// else -> Math.min(nums1[i], nums2[j])// }// return 0.5 * (maxLeft + minRight)
}
}
return0.0
}
funfindMedianSortArray(nums1:ArrayList<Int>): Double {
val m = nums1.size
if (m ==0) {
return0.0
}
val low =0val high = m
val mid = low + (high - low).shr(1)
if (m %2==0) {
return0.5* (nums1[mid] + nums1[mid -1])
} else {
return nums1[mid] *1.0
}
}
@Test
fun_0004() {
// 10 2 4 6 8 9val nums1 =IntArray(5)
nums1[0] =1
nums1[1] =2
nums1[2] =3
nums1[3] =4
nums1[4] =5val nums2 =IntArray(1)
nums2[0] =3val result = findMedianSortedArrays(nums1, nums2)
// val result = findMedianSortArray(arrayListOf(1, 2))print(result)
}
The text was updated successfully, but these errors were encountered:
4. Median of Two Sorted Arrays
There are two sorted arrays nums1 and nums2 of size m and n respectively.
Find the median of the two sorted arrays. The overall run time complexity should be O(log (m+n)).
You may assume nums1 and nums2 cannot be both empty.
Example 1:
Example 2:
题解
这题难度为
hard
, 我思考了一天做不出来,因此参考了star 数目最高的答案, 下面就贴一下该解法, 学习其思想,还要考虑各种边界条件。kotlin 代码见 _0004.kt 文件。解法如下:为了解决这个问题,首先需要明白中位数是什么概念:一组数据分为两组,其中一组总是比另一组小。
针对此题来说,用随机的 i 将 A 分为两部分,注意 i 的位置;
因为 A 有 m 个元素,因此一共有 m + 1 中分割的方法。当 i = 0, 左边为空;
B 也是一样分割方法:
此时将两个部分合并在一起:
此时思考,怎么找到满足题解的答案:
既然求中位数,因此只需要确认:
两个条件,就可以把 A,B 分为长度相等两部分,此时
median = (max(left_part) + min(left_right))/2
上述就是针对中位数作出的分析。
详细步骤
为了确认上述两个条件,只需要确认:
这里解释一下为什么需要 n >= m, 因为在算式中,
j = (m + n) / 2 - i
可能会取到负值,导致结果错误;上述的 A[i-1],B[j-1],A[i],B[j] 即使在 i=0/i=m/j=0/j=n 条件下也成立,后续解释。
因此问题就变为二分查找:
在 [0, m] 找到满足条件的 i, 使得 B[j - 1] <= A[i] && A[i - 1] <= B[j], (j =(m + n) / 2 - i )
步骤如下:
当需要的 i 值找到, 中位数即可得出:
举个例子:
当 A = [1, 2, 3 ,4], B = [2, 3], 时,i = 2, j = 1, left = [1, 2, 2], right = [3, 3, 4], median = 2.5
当 A = [1, 2, 3, 4], B = [2 ,3, 4] i = 2 , j = 1 left = [1, 2, 2], right = [3, 3, 4, 4], median = min(A[i], B[j]) = 3
这里的 j = (m + n) / 2 - i, 当为偶数时, 平均分配;当为奇数是,右边比左边多一个,且右边最小值为中位数。
这时来考虑一下边界条件:
当 i=0,i=m,j=0,j=n 值 A[i-1],B[j-1],A[i],B[j] 不存在,那怎么防止程序崩溃。
目的是找打值满足
max(left_part) <= min(left_right)
。如果 i, j 都不是边界值(意味着 A[i-1],B[j-1],A[i],B[j] 都存在有效),那么需要确认 B[j-1] <= A[i] && A[i-1] <= B[j]。如果 A[i-1],B[j-1],A[i],B[j] 不存在,那么就没必要去确认上述两个条件;比如,i = 0, A[i - 1] 不存在,因此没必要去确认 A[ i - 1] <= B[j]. 因此, 只需要确认:
因此在二分查找的循环中,只需要判断以下条件:
上述条件中, 因为 i < m, j = (m+n+1)/2 - i > (m+n+1)/2 - m >= (2*m+1)/2 - m >= 0, 因此可以不用判断 j > 0; c 条件同上;
上述三个条件互斥, 因此先判断后续两个条件即可。
Accepted
Runtime: 240 ms, faster than 100.00% of Kotlin online submissions for Median of Two Sorted Arrays.
Memory Usage: 44.1 MB, less than 66.67% of Kotlin online submissions for Median of Two Sorted Arrays.
The text was updated successfully, but these errors were encountered: