关于二分查找题型GeneralbinaryLC704BinarysearchsimpleLC34FindthefirstandlastpositionofanelementinasortedarrayMediumv??ariant:rotationArrayLC153Findthethe旋转排序数组的最小值中LC33搜索旋转排序数组中二进制一般技术最常用和最基本的二进制搜索接收一个数组和一个目标值。要找到目标,请返回目标的下标。如果未找到,则返回-1。直接对应LC704functionsearch(nums:number[],target:number):number{letleft:number=0,right:number=nums.length-1while(left<=right){letmid:number=Math.floor(left+(right-left)/2)if(nums[mid]target){right=mid-1}else如果(nums[mid]===target){returnmid}}return-1};注意点:不使用mid=Math.floor((left+right)/2)的主要原因是为了避免超过最大值,而left<=right而不是简单的小于,因为我们需要搜索的区域是一个闭区间,即[left,right],这样我们就可以保证不会漏掉任何一个数。但是,有时候,目标值不止一个,也就是说可能有多个目标值,我们需要找到它的左边界和右边界,所以上面的算法是不可靠的,但是还是可以做一定的改动的以上算法。这里主要学习的是labuladong的算法秘籍中提到的思想。假设在一个新的数组中,[1,2,3,3,3,4],我们要找到target=3的左右边界,怎么办呢?这里直接贴我LC34的解法,98%以上的同学//mainfunctionfunctionsearchRange(nums:number[],target:number):number[]{return[leftBound(nums,target),rightBound(nums,target)]};//求左边界函数leftBound(nums:number[],target:number):number{letleft:number=0,right:number=nums.length-1while(left<=right){让mid:number=Math.floor(left+(right-left)/2)if(nums[mid]target){right=mid-1}else{right=mid-1}}//关键部分if(left>=nums.length||nums[left]!==target){return-1}else{returnleft}}//查找右边界函数rightBound(nums:number[],target:number):number{letleft:number=0,right:number=nums.length-1while(left<=right){letmid:number=Math.floor(left+(里ght-left)/2)if(nums[mid]target){right=mid-1}else{left=mid+1}}//关键部分if(right<0||nums[right]!==target){return-1}else{returnright}}这道题的意思很简单,就是让我们找左找右boundaries,那我们就分别找吧如果仔细看左右边界,会发现和基本的差别不大,只是多了两行判断结果。然后当nums[mid]===target时,我们并没有输出,而是缩小了边界继续搜索。重要的部分是了解何时跳出循环。我们给出的条件是左<=右。因此,当left>right时,我们可以跳出循环。首先考虑leftBound函数。当nums[mid]刚好等于左边界时,我们的右会再次收缩到左边界-1的位置。之后left会继续增加,直到等于right,最后left=mid+1刚好大于right等于左边框的位置。跳出循环后,再次判断,因为我们没有考虑两种极端情况,一种是左边超出边界,一种是找到的左边边界不等于目标,所以计算结果是正确的.旋转数组:二分查找的变种leetcode中关于旋转数组的题很多,这里说两个。一种是LC153最基本的旋转阵列。比如[3,4,5,0,1,2]就是一个典型的旋转数组,我们可以找到规律,就是除了中间点是无序的,其余都是有序的,那么我们就不是通过二分法搜索能找到这个旋转点吗?(有的同学选择直接遍历,也不是不可以,但是当数据量巨大的时候,时间复杂度很高)本题我们只需要输出0,也就是所谓的旋转点。直接粘贴答案functionfindMin(nums:number[]):number{letleft:number=0,right:number=nums.length-1while(leftnums[right]){left=mid+1}}returnnums[left]};这里还有一个比较棘手的地方,为什么是leftnums[spin-1]){return-1}elseif(目标>nums[nums.length-1]){returnbinarySearch(nums,target,0,spin-1)}elseif(target<=nums[nums.length-1]){returnbinarySearch(nums,target,spin,nums.length-1)}};functionfindSpinIndex(nums:number[]):number{让左:number=0,right:number=nums.length-1while(leftnums[right]){left=mid+1}}returnleft}functionbinarySearch(nums:number[],target:number,leftBound:number,rightBound:number):number{letleft:number=leftBound,right:number=rightBoundwhile(left<=right){letmid:number=Math.floor(left+(right-left)/2)if(nums[mid]>target){right=mid-1}elseif(nums[mid]