feat: 添加二分查找33,34,35,74

This commit is contained in:
LouisFonda 2025-06-22 00:26:03 +08:00
parent 21d1a55888
commit 81d4ae749b
Signed by: yigencong
GPG Key ID: 29CE877CED00E966
4 changed files with 185 additions and 0 deletions

View File

@ -0,0 +1,46 @@
/**
* @param {number[]} nums
* @param {number} target
* @return {number}
*/
const search = function (nums, target) {
};
/*
思路按照题目描述数组旋转之后会变成两段有序的序列而且第一段有序序列一定是大于第二段有序序列的
可以直接利用二分查找但是在查找的时候要留意mid落在那一段序列上如果落在第一段序列上 nums[mid] >= nums[left],
反之第二段知道mid落在那一段序列之后我们还需判断target在那一段序列上如果mid在第一段target也在第一段并且
小于nums[mid]收缩右边界为mid-1如果在第二段收缩左边界为mid+1
*/
function f1(nums, target) {
let left = 0;
let right = nums.length - 1;
while (left <= right) {
const mid = left + ((right - left) >> 1);
if (nums[mid] === target) {
return mid; // 找到目标值,直接返回
}
// 如果mid落在第一段那么nums[mid] >= nums[0], 否则落在第二段
if (nums[mid] >= nums[0]) {
// 如果target在第一段,并且target < nums[mid]
if (target > -nums[0] && target < nums[mid]) {
right = mid - 1;
} else {
left = mid + 1;
}
} else {
// 如果target落在第二段并且target > nums[mid]
// eslint-disable-next-line no-lonely-if
if (target <= nums[nums.length - 1] && target > nums[mid]) {
left = mid + 1;
} else {
right = mid - 1;
}
}
}
return -1; // 没有找到目标值
}

View File

@ -0,0 +1,40 @@
/**
* @param {number[]} nums
* @param {number} target
* @return {number[]}
*/
const searchRange = function (nums, target) {
};
function searchRange(nums, target) {
let left = 0, right = nums.length - 1;
let start = -1, end = -1;
// Find the first occurrence
while (left <= right) {
let mid = Math.floor((left + right) / 2);
if (nums[mid] >= target) {
right = mid - 1;
} else {
left = mid + 1;
}
}
start = nums[left] === target ? left : -1;
// Find the last occurrence
left = 0;
right = nums.length - 1;
while (left <= right) {
let mid = Math.floor((left + right) / 2);
if (nums[mid] <= target) {
left = mid + 1;
} else {
right = mid - 1;
}
}
end = nums[right] === target ? right : -1;
return [start, end];
}

View File

@ -0,0 +1,32 @@
/**
* @param {number[]} nums
* @param {number} target
* @return {number}
*/
const searchInsert = function (nums, target) {
};
/*
直接利用二分查找
*/
let pos = nums.length;
let left = 0;
let right = nums.length - 1;
// 二分查找知道left>right结束查找
while (left <= right) {
const mid = Math.floor((left + right) / 2);
// 如果target<nums[mid] 则更新pos
if (target === nums[mid]) return mid;
if (target < nums[mid]) {
pos = mid;
right = mid - 1;
continue;
}
left = mid + 1;
}
return pos;

View File

@ -0,0 +1,67 @@
/**
* @param {number[][]} matrix
* @param {number} target
* @return {boolean}
*/
const searchMatrix = function (matrix, target) {
};
/*
将二维矩阵转换成一维数组然后利用二分查找来查找目标值
*/
function f1(matrix, target) {
const nums = matrix.flat(); // 将二维矩阵转换为一维数组
let left = 0;
let right = nums.length - 1;
while (left <= right) {
const mid = left + Math.floor(right - left) / 2;
if (nums[mid] === target) {
return true; // 找到目标值
} if (nums[mid] < target) {
left = mid + 1; // 目标值在右半部分
} else {
right = mid - 1; // 目标值在左半部分
}
}
return false; // 矩阵中没有这个值
}
/*
两次二分查找第一次找第一列中小于等于target的那个值第二次找这一个值是否在这一行存在存在返回true,不存在返回false
*/
function f2(matrix, target) {
// 二分查找第一列这里使用upper_bound的方式
let left = 0;
let right = matrix.length;
while (left < right) {
const mid = left + Math.floor((right - left) / 2); // 使用靠右的计算防止死循环
if (matrix[mid][0] <= target) {
left = mid + 1;
} else {
right = mid;
}
}
const row = left - 1; // 右边界减1就是我们要找的值
// 如果右边界小于0表示要找的数不存在矩阵中直接返回false
if (row < 0) return false;
// 二分查找这一行
left = 0;
right = matrix[row].length;
while (left <= right) {
const mid = left + Math.floor((right - left) / 2);
if (matrix[row][mid] === target) {
return true; // 找到目标值
} if (matrix[row][mid] < target) {
left = mid + 1; // 目标值在右半部分
} else {
right = mid - 1; // 目标值在左半部分
}
}
return false; // 矩阵中没有这个值
}