欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 新闻 > 焦点 > 【LeetCode 热题 100】二分查找 系列

【LeetCode 热题 100】二分查找 系列

2025/5/23 13:58:54 来源:https://blog.csdn.net/jupangMZ/article/details/148032708  浏览:    关键词:【LeetCode 热题 100】二分查找 系列

📁 35. 搜索插入位置

        将数组划分为两个区间[0 , left] [right , n],其中有 左区间的元素都小于targe,右区间的元素都大于等于target。 

        left指针维护左区间结束位置,right维护右区间的起始位置,right所在位置一定是第一个大于等于target的位置

class Solution {
public:int searchInsert(vector<int>& nums, int target) {int left = 0 , right = nums.size();while(left < right){int mid = (left + right) >> 1;if(nums[mid] < target)left = mid + 1;else    right = mid;}return left; 循环结束 此时left==right}
};

📁 74. 搜索二维矩阵

        这一道题目还是类似上一道题目,只不过多加了一层循环。

class Solution {
public:bool searchMatrix(vector<vector<int>>& matrix, int target) {int m = matrix.size() , n = matrix[0].size();for(int i = 0 ; i < m ; ++i){int left = 0 , right = n - 1;while(left < right){int mid = (left + right) >> 1;if(matrix[i][mid] < target)left = mid + 1;elseright = mid;}if(matrix[i][right] == target)return true;}return false;}
};

📁 34. 在排序数组中查找元素的第一个和最后一个位置

        进行两次二分,寻找左区间的右端点 以及 寻找右区间的左端点。

class Solution {
public:vector<int> searchRange(vector<int>& nums, int target) {if(nums.size() == 0)return {- 1 , -1};int n = nums.size();int left = 0 , right = n - 1;int begin = -1 , end = -1;while(left < right){int mid = (left + right) >> 1;if(nums[mid] < target)left = mid + 1;elseright = mid;}if(nums[left] != target)return {begin , end};begin = left , left = 0 , right = n - 1;while(left < right){int mid = (left + right + 1) >> 1;if(nums[mid] > target)right = mid - 1;elseleft = mid;}end = right;return {begin , end};}
};

📁 33. 搜索旋转排序数组

    二分的条件就是: 有序或部分有序

    1. 进行二分后,一定会后一个有序数组,有一个或有序或无序的数组,例如:

        a.  4  5  6  [7]  0  1  2

        b.  6  7  0  [1]  2  4  5

    2. 根据有序数组,缩小搜索范围

class Solution {
public:int search(vector<int>& nums, int target) {int n = nums.size();int left = 0 , right = n - 1;while(left <= right){int mid = (left + right) >> 1;if(nums[mid] == target)return mid;if(nums[left] <= nums[mid]){if(target >= nums[left] && target <= nums[mid])right = mid - 1;else    left = mid + 1;}else{if(target >= nums[mid + 1] && target <= nums[right])left = mid + 1;else    right = mid - 1;}}return -1;}
};

📁 153. 寻找旋转排序数组中的最小值

将 mid 和 数组最后一个元素n 比较:

1. mid > n , 说明数组一定被划分成为两段,其中第一段的元素均大于第二段的元素

2. mid <= n , 说明x要么是最小值,要么最小值在右边(nums本身是递增数组, 只有一段)  

int findMin(vector<int>& nums) {int left = 0 , right = nums.size() - 1;int x = nums[nums.size() - 1];while(left < right){int mid = (left + right) >> 1;if(nums[mid] > x)left = mid + 1;else right = mid;}return nums[left];}

📁 4. 寻找两个正序数组的中位数

规则: 使用一条分割线把两个数组分割成两个部分

1. 左边和右边的元素个数相等,或左边元素的个数比右边个数的多1个

2. 左边元素之和 <= 右边元素之和 (若不满足交叉小于等于的关系 就需要调整分割线的位置)

    中位数一定就与分割切两侧的元素相关 确定这个红线使用二分查找

    交叉小于等于:

      arr1[分割线左侧元素] <= arr2[分割线右侧元素] && arr2[分割线左侧元素] <= arr1[分割线右侧元素]

    因为需要通过访问分割线左右两边的元素,因此应该在较短的数组上确定分割线的位置

    i: 第一个数组分割线右边的第一个元素的下标 i = 第一个数组分割线左侧元素的个数

    j: 第二个数组分割线右边的第一个元素的下标 j = 第二个数组 分割线左侧元素的个数

class Solution {
public:double findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2) {//需要访问 "中间分割线" 左右两边的元素,因此需要在较短的数组上确定 "中间分割线"的位置,避免越界if(nums1.size() > nums2.size()) {vector<int> tmp = nums1;nums1 = nums2;nums2 = tmp;}//通过元素个数较少的的数组确定分割线数量,避免数组越界int m = nums1.size() , n = nums2.size();int totalLeft = (m + n + 1) / 2;    //表示合并后数组中​​左半部分的元素数量​​int left = 0 , right = m;while(left < right){int i = left + (right - left + 1) / 2;int j = totalLeft - i;if(nums1[i - 1] > nums2[j])right = i - 1;elseleft = i; }int i = left , j = totalLeft - i;//处理边界情况int num1LeftMax = i == 0 ? INT_MIN : nums1[i - 1];int num1RightMin = i == m ? INT_MAX : nums1[i];int num2LeftMax = j == 0 ? INT_MIN : nums2[j-1];int num2RightMin = j == n ? INT_MAX : nums2[j];if((m + n ) % 2 == 1)return max(num1LeftMax , num2LeftMax);elsereturn (double)((max(num1LeftMax , num2LeftMax) + min(num1RightMin , num2RightMin))) / 2;}   
};

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词