还是需要看原始解释,英文解释,多看几遍,多想想,就明白了。中文的文章不够清晰的。
1 详解过程:
视频
2 定义:
3 自己翻译下 - 中位数特点:
- 把一个集合分割为长度相等的子集
- 其中一个子集元素总是大于另一个
也可参考wiki:
4 把答案整理为js代码:
var findMedianSortedArrays = function(A, B) { var m = A.length; var n = B.length; if (m > n) { // to ensure m<=n var temp = A; A = B; B = temp; var tmp = m; m = n; n = tmp; } var iMin = 0, iMax = m, halfLen = Math.floor((m + n + 1) / 2); while (iMin <= iMax) { var i = Math.floor((iMin + iMax) / 2); var j = halfLen - i; if (i < iMax && B[j - 1] > A[i]) { iMin = i + 1; // i is too small } else if (i > iMin && A[i - 1] > B[j]) { iMax = i - 1; // i is too big } else { // i is perfect var maxLeft = 0; if (i == 0) { maxLeft = B[j - 1]; } else if (j == 0) { maxLeft = A[i - 1]; } else { maxLeft = Math.max(A[i - 1], B[j - 1]); } if ((m + n) % 2 == 1) { // 如果奇数,则直接返回maxLeft;不然,则找到minRight return maxLeft; } var minRight = 0; if (i == m) { minRight = B[j]; } else if (j == n) { minRight = A[i]; } else { minRight = Math.min(B[j], A[i]); } // 偶数,返回平均值 return (maxLeft + minRight) / 2; } } return 0;}复制代码
5 其他
1 为什么会有第二个红线的公式?
原来是从第一个红线换算得出的:
代码中其实就是: var j = halfLen - i; // halfLen = Math.floor((m + n + 1) / 2);
2 找到后,为什么奇数的中位数是比较最大值max(A[i-1],B[j-1]),而不是比较最小值min(A[i],B[j])?
因为一开始是用随机数i来切分数组的,如下图:
3 其他两个条件中,为什么要限定i<m和i>0?
初步觉得是一开始要求0<i<m,而条件1中是i=m或i=0,所以条件2和条件3肯定是i<m和i>0。
不用j>0和j<n条件,下面有解释了:(从i<m可得出j>0;从j>0可得出j<n)
6 想法不定时更新
- 记得原来数组A和数组B是已经排好序的,所以只需比较A[i-1]<=B[j]和B[j-1]<=A[i]。因为A[i-1]肯定小于等于A[i],B[j-1]肯定小于等于B[j]。具体可参考视频 -- 0519 22.31