数据结构-二分查找(Java版)

二分查找也称折半查找(Binary Search),它是一种效率较高的查找方法。但是,折半查找要求数组必须是升序。

时间复杂度为O(log n)。

Java中Arrays.binarySearch()

以下是Java版的二分查找,同时Java中Arrays工具类也提供了二分查找方法Arrays.binarySearch(int a, int key);

参数:

a - 要搜索的数组

key - 要搜索的值

返回:

如果它包含在数组中,则返回搜索键的索引;否则返回 (-(插入点) - 1)。插入点 被定义为将键插入数组的那一点:即第一个大于此键的元素索引,如果数组中的所有元素都小于指定的键,则为 a.length。注意,这保证了当且仅当此键被找到时,返回的值将 >= 0。

使用二分搜索法来搜索指定的 int 型数组,以获得指定的值。必须在进行此调用之前对数组进行排序(通过 sort(int[]) 方法)。如果没有对数组进行排序,则结果是不确定的。如果数组包含多个带有指定值的元素,则无法保证找到的是哪一个。

二分查找源码:

public static int binarySearch(int[] a, int key) {
    return binarySearch0(a, 0, a.length, key);
}


private static int binarySearch0(int[] a, int fromIndex, int toIndex, int key) {
    int low = fromIndex;
    int high = toIndex - 1;

    while (low <= high) {
        int mid = (low + high) >>> 1;
        int midVal = a[mid];

        if (midVal < key)
            low = mid + 1;
        else if (midVal > key)
            high = mid - 1;
        else
            return mid; // key found
    }
    return -(low + 1);  // key not found.
}

数据结构二分查找实现

/***
 *
 * @param a - 待查找的升序数组
 * @param target - 待查找的目标值
 * @return 返回 target的索引,找不到则返回-1
 */
public int search(int[] a , int target){
    int i = 0;
    int j = a.length-1;
    while (i <= j){
        int m = (i+j) >>> 1;
        if (target < a[m]){
            j = m-1;
        }else if (a[m] < target){
            i = m+1;
        }else {
            return m;
        }
    }
    return -1
}

二分查找-改良版,返回最左边索引

若数组[0,3,5,5,5,7,10,12],元素有重复时,返回大于等于target最左边索引。适用场景:求排名,搜索插入位置

/***
 *
 * @param a - 待查找的升序数组
 * @param target - 待查找的目标值
 * @return 返回 >= target的最靠左索引
 */
public int binarySearchLeft(int[] a , int target){
    int i = 0,  j = a.length;
    while ( i <= j){
        int m = (i + j) >>> 1;
        if ( target <= a[m]){
            j = m-1;
        }else {
            i = m+1;
        }
    }
    return i;
}

二分查找-改良版,返回最右边索引

若数组[0,3,5,5,5,7,10,12],元素有重复时,返回小于等于target最右边索引。适用场景:求前任,求后任。

/***
 *
 * @param a - 待查找的升序数组
 * @param target - 待查找的目标值
 * @return 返回 <= target的最靠右索引
 */
public int binarySearchRight(int[] a , int target){
    int i = 0,  j = a.length;
    while ( i <= j){
        int m = (i + j) >>> 1;
        if ( target < a[m]){
            j = m-1;
        }else {
            i = m+1;
        }
    }
    return i-1;
}

LeetCode-704题-二分查找

题解

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

LeetCode-35题-搜索插入位置

题解:

class Solution {
    public int searchInsert(int[] nums, int target) {
        int i = 0, j = nums.length - 1;
        while(i <= j){
            int m = (i+j) >>> 1;
            if(target <= nums[m]){
                j = m - 1;
            }else{
                i = m + 1;
            }
        }
        return i;
    }
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值