当前位置: 首页 > 后端技术 > Java

【数据结构与算法】1.二分查找

时间:2023-04-02 00:06:07 Java

是第一次写文章。如有不妥,欢迎指正基础二分法。前提条件:有序数组形式:二分法一般有两种写法。对应不同的区间定义。根据定义,区间是不变量。在二分查找的过程中,必须保持不变性,即在while查找中,每一次边界处理都必须按照区间的定义进行操作,这就是循环不变性的规则。一种是左闭右闭,即[left,right],另一种是左闭右开,即[left,right)第一种写法:[left,right],即目标就在这个闭区间。首先,while的循环条件必须是left<=right,因为只有left=right时,才能考虑区间的右端点(即right)。因为当left>1target),则说明target值在[left,mid)区间内。由于我们考虑的是闭区间[left,right],所以right应该设置为mid-1。这种写法最后的right=left-1;第二种写法:[left,right)首先,while循环的条件是lefttarget),right应该更新为mid,因为搜索区间是左闭右开interval,nums[mid]不等于target,所以right更新为mid。这种写法在左=右时结束。二分法的变体要改变二分法,关键是要注意循环过程中不同if条件下指针的移动,以及循环最终终止时的左右关系。以leetcode题目34.查找一个元素在排序数组中的第一个和最后一个位置为例:在这个题目中,目标有重复的值,所以主要修改两种基本写法最终定位到的目标的位置。这里参考leetcode用户jys_std的注释代码。找第一个位置我们可以理解为找第一个大于等于target的位置,找最后一个位置就是找第一个大于等于target+1的位置,这样就达到了统一。我们知道基本的二分法就是找单个元素的位置,那么如何修改它找到大于等于给定元素的第一个位置呢?这里我们以第二种写法(左闭右开)为例。下面是底层二分法的示例Java代码:publicintsearch(int[]nums,inttarget){intleft=0,right=nums.length;while(left>1;if(nums[mid]target)右=中;如果(nums[mid]==target)返回mid;}返回-1;}给出本题变体代码://findthefirstpublicintsearch(int[]nums,inttarget){intl=0,r=nums.length;while(l>1;如果(nums[mid]>=target)r=mid;否则l=中间+1;}返回l;注意循环过程中不同if条件下指针的移动以及循环最终结束时的左右关系。首先,当nums[mid]=target的时候,我们不能return,因为会有多个target,所以我们这个时候要找的是最左边的target,不知道这个是不是最左边的,但是我们可以确认不考虑右区间(mid,right),只考虑区间[left,mid)。所以这时候我们就设置为mid。然后考虑nums[mid]>target的情况。这时候和第一种情况一样,right也设置为mid。然后我们看nums[mid]