合并两个有序数组
合并两个有序数组
题目
给定两个大小分别为 m 和 n 的正序(从小到大)数组 nums1 和 nums2。请你找出并返回这两个正序数组的 中位数 。
算法的时间复杂度应该为 O(log (m+n)) 。
示例 1:
输入:nums1 = [1,3], nums2 = [2]
输出:2.00000
解释:合并数组 = [1,2,3] ,中位数 2
示例 2:
输入:nums1 = [1,2], nums2 = [3,4]
输出:2.50000
解释:合并数组 = [1,2,3,4] ,中位数 (2 + 3) / 2 = 2.5
求解
1 | /** |
二分查找
一看就会,一写就废。问题出在边界无法掌握,一不小心就死循环了,因此要掌握二分查找的边界
https://blog.csdn.net/qq_45978890/article/details/116094046
二分查找的条件
- 有序
- 只找一个
二分查找的边界
1、[左闭,右闭]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19const search1 = (arr, target) => {
let left = 0, right = arr.length - 1;
// 二分查找,闭区间
while (left <= right) { // 因为是闭区间,所以left 要小于等于right
let mid = left + Math.floor((right - left) / 2);
if (arr[mid] < target) { // 目标值在右边
left = mid + 1; //应为是左闭右闭,所以不用担心,边界mid+1后mid+1不能被比较
}
else if (arr[mid] > target) { // 目标值在左边
right = mid - 1;
} else {
// 找到目标值
return mid;
}
}
return -1;
}
//犯个错误,第二个else if,我用了if,然后下面用了else,导致第二个if和最后的else成了组合,不再能表示所有情况。
console.log(search([1,2,3,4,5,6,7,8,9], 5)) // 42、[左闭,右开)
1
2
3
4
5
6
7
8
9
10
11
12
13const search = (arr, target) => {
let left = 0, right = arr.length; // 左闭右开区间
while (left < right) { //终止条件
let mid = left + Math.floor((right - left) / 2);
if (arr[mid] < target) { // 目标值在右边
left = mid + 1; // 更新左边界
} else if (arr[mid] > target) { // 目标值在左边
right = mid; // 更新右边界
} else {
return mid;
}
}
}3、(左开,右闭]
1
2
3
4
5
6
7
8
9
10
11
12
13
14//左开右闭区间
const search = (arr, target) => {
let left = -1, right = arr.length - 1; // 左开右闭区间
while (left < right) { //终止条件
let mid = left + Math.floor((right - left + 1) / 2);
if (arr[mid] < target) { // 目标值在右边
left = mid; // 更新左边界
} else if (arr[mid] > target) { // 目标值在左边
right = mid - 1; // 更新右边界
} else {
return mid;
}
}
}4、开区间写法
const search4 = (arr, target) => {
let left = -1, right = arr.length; // 开区间
while (left + 1 < right) { //终止条件
let mid = left + Math.floor((right - left) / 2);
if (arr[mid] < target) { // 目标值在右边
left = mid; // 更新左边界
} else if (arr[mid] > target) { // 目标值在左边
right = mid; // 更新右边界
} else {
return mid;
}
}
}```