欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 房产 > 家装 > 【LeetCode Hot100】二分查找篇

【LeetCode Hot100】二分查找篇

2025/5/5 9:09:02 来源:https://blog.csdn.net/ZZZioz/article/details/147679300  浏览:    关键词:【LeetCode Hot100】二分查找篇

前言

        本文用于整理LeetCode Hot100中题目解答,因题目比较简单且更多是为了面试快速写出正确思路,只做简单题意解读和一句话题解方便记忆。但代码会全部给出,方便大家整理代码思路。

二分相关问题讲解:【基础算法】二分查找的多种写法


35. 搜索插入位置

一句话题意

        给定一个序列和一个目标值,问若目标值存在序列中,则返回下标,否则返回目标值插入有序序列的位置。

一句话题解

        二分查找。

class Solution {public int searchInsert(int[] nums, int target) {int l=0;int r=nums.length;while(l<r){int mid=l+r>>1;if(nums[mid]>=target){r=mid;}else{l=mid+1;}}return r;}
}

74. 搜索二维矩阵

一句话题意

        给定一个每行递增,每行最后一个值大于下一行第一个值得二维矩阵,问目标值是否在矩阵中。

一句话题解

        两次二分,先去最后一列二分查目标值所在行,然后在所在行查所在列。

class Solution {int n,m;int target;int[][] matrix;public boolean searchMatrix(int[][] matrix, int target) {this.n=matrix.length;this.m=matrix[0].length;this.target=target;this.matrix = matrix;int x = searchY(m-1);if(x==n)x--;int y = searchX(x);if(y==m)y--;return matrix[x][y]==target;}int searchX(int x){int l=0;int r=m;while(l<r){int mid=l+r>>1;if(matrix[x][mid]<target){l=mid+1;}else{r=mid;}}return r;}int searchY(int y){int l=0;int r=n;while(l<r){int mid=l+r>>1;if(matrix[mid][y]<target){l=mid+1;}else{r=mid;}}return r;}
}

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

一句话题意

        顾名思义,在排序数组中查找元素的第一个和最后一个位置。

一句话题解

        实现lower_bound和upper_bound。

class Solution {public int[] searchRange(int[] nums, int target) {int l=lowBs(nums,target);if(l==nums.length||nums[l]!=target){return new int[]{-1,-1};}if(l==nums.length-1){return new int[]{l,l};}return new int[]{l,highBs(nums,target)-1};}int lowBs(int[] nums,int target){int l=0;int r=nums.length;while(l<r){int mid=l+(r-l>>1);if(nums[mid]<target){l=mid+1;}else{r=mid;}}return l;}int highBs(int[] nums,int target){int l=0;int r=nums.length;while(l<r){int mid=l+(r-l>>1);if(nums[mid]<=target){l=mid+1;}else{r=mid;}}return l;}
}

33. 搜索旋转排序数组

一句话题意

        有序数组吗,在顺时针旋转了一定范围,求目标值是否存在数组中。

一句话题解

        二分。可以注意到的是,我们在进行二分的时候,一定是有一半的序列是有序的,那么我们可以根据这个特点,去分类判断即可。

class Solution {public int search(int[] nums, int target) {int l=0;int r=nums.length-1;while(l<=r){int mid=l+(r-l>>1);if(nums[mid]==target)return mid;if(nums[0]<=nums[mid]){if(nums[0]<=target&&target<nums[mid]){r=mid-1;}else{l=mid+1;}}else{  if(nums[mid]<target&&target<=nums[nums.length-1]){l=mid+1;}else{r=mid-1;}}}return -1;}
}

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

一句话题意

        求旋转后的有序序列中的最小值。

一句话题解

        二分,可以发现的是,在我们旋转之后,我们二分的中间元素若大于右侧元素,那我们可以判断出最小值应该在mid的右侧;否则在左侧。

        本质上就是找小的递增序列的位置。

class Solution {public int findMin(int[] nums) {int l = 0;int r = nums.length - 1;while (l < r) {int mid = l + (r - l >> 1);if (nums[mid] < nums[r]) {r = mid;} else {l = mid + 1;}}return nums[l];}
}

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

一句话题意

        给定两个有序序列,问两个有序序列组合成一个组合序列后的中位数是什么。

一句话题解

参考题解:【图解】循序渐进:从双指针到二分 -- 灵茶山艾府

        要求复杂度最大O(log(n+m)),可以观察到我们通过将序列中的值分为相同数量的两部分,左边取最大值,右侧取最小值,就能取得中位数。以此,我们可以将两个序列根据不同的序列划分点,算出当左侧最大值小于右侧最小值的时候,是满足条件的,也就是可以正确取得中位数。据此,我们可以进行二分。

class Solution {public double findMedianSortedArrays(int[] nums1, int[] nums2) {if(nums1.length>nums2.length){int[] tmp=nums1;nums1=nums2;nums2=tmp;}int n=nums1.length;int m=nums2.length;int l=-1;int r=n;while(l+1<r){int midt=l+(r-l>>1);int midb=(m+n+1>>1)-midt-2;if(nums1[midt]<=nums2[midb+1]){l=midt;}else{r=midt;}}int i=l;int j=(m+n+1>>1)-i-2;int mxt=Integer.MIN_VALUE;int mxb=Integer.MIN_VALUE;int mnt=Integer.MAX_VALUE;int mnb=Integer.MAX_VALUE;if(i>=0)mxt=nums1[i];if(j>=0)mxb=nums2[j];if(i+1<n)mnt=nums1[i+1];if(j+1<m)mnb=nums2[j+1];if((n+m)%2==0){return (Math.min(mnt,mnb)+Math.max(mxt,mxb))/2.0;}else{return Math.max(mxb,mxt);}}
}

版权声明:

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

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

热搜词