算法之二分查找法

二分查找法总结:

第一:使用条件为有序或者部分有序的数组

第二:一定要弄清楚整个算法是在左闭右闭还是左闭右开的区间内完成

第三:为了有效的防止中间数据的溢出,所以mid条件一般写为:Mid = left +((right – left)/ 2)

代码:左闭右闭 [left,right]

     注意点1:为什么while循环的条件是left<=right,而不是left

    总的来说这里的循环条件只要满足区间是合法就ok了 

    注意点 2:为了防止在计算mid值时数组的越界情况,一般建议使用mid = left + ((right - left)/2)

                    是等同于下面代码所提供的mid = (left + right) / 2的

   注意点3:对于right 到底是mid + 1还是mid的情况 也是结合着你到底是闭区间还是开区间来结合的,代码块里面有说明此处就不再重述了。

/**
 * 输入: nums = [1,3,5,6], target = 2
 * 输出: 1
 */
// 二分查找法
public static int searchInsert4(int[] nums, int target) {
    int left = 0;
    int right = nums.length - 1; // 注意边界是[left,right] // [0,3]
    while (left <= right){   // 所以此处循环是left<=right
        int mid = (left+right)/2; // 取left和right的中间值mid 注意:此处可能会出现int越界的情况
        if (nums[mid]>target){ // 当中间值小于了目标值,那么说明目标值在[left,mid]这个区间,所以需要更新right值
            right = mid - 1;  // 此处为什么是mid-1。由于我们是左闭右闭的区间,在if条件中已经明确知道了mid处的值是大于了目标值所以可以明确目标值所在数组位置一定是在区间为[left,mid-1]
        } else if (nums[mid] < target){ // 当中间值大于了目标值,那么说明目标值在[mid,right]这个区间,所以需要更新left值
            left = mid + 1; // 此处为什么是mid+1。由于我们是左闭右闭的区间,在if条件中已经明确知道了mid处的值是小于了目标值所以可以明确目标值所在数组位置一定是在区间为[mid+1,right]
        } else { // 最后就是mid = 目标值的情况,直接放回mid的即是目标值在数组中的位置
            return mid;
        }
    }
    return -1; // 目标值不在数组的情况可以选择放回-1
}

代码:左闭右开 [left,right])

     注意点同上述,理解好区间的合法性就能理解此处代码

 /**
     * nums = [1,3,5,6], target = 2
     */
    public static int searchInsert5(int[] nums, int target) {
        if (nums[0] > target){
            return 0;
        }
        int left = 0;
        int right = nums.length; // 注意边界是[left,right] // [0,4)
        while (left < right){   // 所以此处循环是lefttarget){ // 当中间值小于了目标值,那么说明目标值在[left,mid]这个区间,所以需要更新right值
                right = mid;  // 此处为什么是mid-1。由于我们是左闭右闭的区间,在if条件中已经明确知道了mid处的值是大于了目标值所以可以明确目标值所在数组位置一定是在区间为[left,mid-1]
            } else if (nums[mid] < target){ // 当中间值大于了目标值,那么说明目标值在[mid,right]这个区间,所以需要更新left值
                left = mid + 1; // 此处为什么是mid+1。由于我们是左闭右闭的区间,在if条件中已经明确知道了mid处的值是小于了目标值所以可以明确目标值所在数组位置一定是在区间为[mid+1,right]
            } else { // 最后就是mid = 目标值的情况,直接放回mid的即是目标值在数组中的位置
                return mid;
            }
        }
        return nums.length; // 目标值不在数组的情况可以选择放回-1
    }

你可能感兴趣的:(数据结构)