二分查找法

首先引入一下二分查找法的概念:

二分查找又称为折半查找。前提是,表中元素是按升序排列,将表中间位置记录的关键字与查找关键字比较,如果两者相等,则查找成功;否则利用中间位置记录将表分成前、后两个子表,如果中间位置记录的关键字大于查找关键字,则进一步查找前一子表,否则进一步查找后一子表。重复以上过程,直到找到满足条件的记录,使查找成功,或直到子表不存在为止,此时查找不成功。


平时我们做题的时候可能会遇到不知道循环条件带不带等号,右边界减不减一,左边界加不加加一的问题

接着可以用一个例题来进行引入,进行讲解,

参考的是leetcode上第704题,

题目: 

代码块:

class Solution {
    public int search(int[] nums, int target) {
        int left=0;
        int right=nums.length-1;
        int middle;
        while(left<=right){
            middle=left+(right-left)/2;
            if(nums[middle]>target)
            right=middle-1;
            else if(nums[middle]

1.首先要考虑区间的范围,是左开右闭,还是左闭右闭,这个就是循环不变量

左开右闭就是说这个区间是包含left,但是不包含right;而左闭右闭是既包含left又包含right。

接下来在写代码的时候就可以确定循环不变量了,left到底是<还是<=right,由于这个题目是左闭右闭的,那么看一下如果是<=区间是否合法,比如[3,3]是可以满足的。

接下来就可以完成一部分代码了

       //定义变量
        int left=0;
        int right=nums.length-1;
        int middle;
        //循环不变量
        while(left<=right){
            middle=left+(right-left)/2;

2.对于循环里面,我们要判断left,right是mid-1,还是mid+1,还是mid

            if(nums[middle]>target)
            right=middle-1;
            else if(nums[middle]

对于如果中间数大于目标值,是要更新right的,那right的话,这个区间是左闭右闭的区间,我们已经判断这个middle所在值大于target,也就是说nums[middle]一定不是要搜素的值,接下来的区间是一定不要包含这个值的,因为如果包含的话是会造成死循环的,接下来的右值right便是midlle-1.

同样,对于左值,如果middle所在值小于target,那么就是nums[middle]一定不是要搜索的值,接下来的区间是不要包含这个值的,接下来左值就是middle+1.

同样可以写一下左开右闭的,先判断循环不变量,如果用<=的话,(3,3]是不合法的,那么就有了left


具体内容可以参考b站上代码随想录的视频。

你可能感兴趣的:(数据结构与算法,算法,数据结构)