《编程之美》-二分查找的实现

二分查找

找出一个有序的字符串数组arr中值等于字符串v的元素的序号,并返回其序号,否则返回-1;

private static int binarySearch(String[] arr, String str) {
    int l = 0, r = arr.length-1;
    while (l <= r) {
        int mid = l + (r-l) / 2;
        if (arr[mid].equals(str)) return mid;
        else if (arr[mid].compareTo(str) < 0) l = mid+1;
        else if (arr[mid].compareTo(str) > 0) r = mid-1;
    }
    return -1;
}

public static void main(String[] args) {
    String[] s = {"a", "bcd", "cc", "cc", "cc", "sad"};
    System.out.println(binarySearch(s, "rad"));
}

找出一个有序的字符串数组arr中值等于字符串v的元素的序号,如果有多个元素满足这个条件,请返回序号中最大的那个;

private static int binarySearch(String[] arr, String str) {
    int l = 0, r = arr.length-1;
    while (l < r - 1) {
        int mid = l + (r-l) / 2;
        if (arr[mid].compareTo(str) <= 0) l = mid;
        else if (arr[mid].compareTo(str) > 0) r = mid;
    }
    if (arr[r].equals(str)) return r;
    else if (arr[l].equals(str)) return l;
    else return -1;
}

找出一个有序的字符串数组arr中值等于字符串v的元素的序号,如果有多个元素满足这个条件,请返回序号中最小的那个;

    private static int binarySearch(String[] arr, String str) {
        int l = 0, r = arr.length-1;
        while (l < r - 1) {
            int mid = l + (r-l) / 2;
            if (arr[mid].compareTo(str) >= 0) r = mid;
            else if (arr[mid].compareTo(str) < 0) l = mid;
        }
        if (arr[l].equals(str)) return l;
        else if (arr[r].equals(str)) return r;
        else return -1;
    }

找出一个有序的字符串数组arr中最大的arr[i]小于v,并返回 i ,如不存在则返回-1;

private static int binarySearch(String[] arr, String str) {
    int l = 0, r = arr.length-1;
    while (l < r - 1) {
        int mid = l + (r-l) / 2;
        if (arr[mid].compareTo(str) >= 0) r = mid;
        else if (arr[mid].compareTo(str) < 0) l = mid;
    }
    if (arr[l].equals(str)) return l - 1;
    else if (arr[r].equals(str)) return l;
    else return l - 1;
}

找出一个有序的字符串数组arr中最小的arr[i]大于v,并返回 i ,如不存在则返回-1;

    private static int binarySearch(String[] arr, String str) {
        int l = 0, r = arr.length-1;
        while (l < r - 1) {
            int mid = l + (r-l) / 2;
            if (arr[mid].compareTo(str) <= 0) l = mid;
            else if (arr[mid].compareTo(str) > 0) r = mid;
        }
        if (arr[r].equals(str)) return r+1 == arr.length ? -1 : r+1;
        else if (arr[l].equals(str)) return r;
        else return r+1 == arr.length ? -1 : r+1;
    }

注意

  • 如果只是需要找到任意一个相等的值并返回序号的话(最普通的二分查找),因为在while中就可以返回,所以分三种情况,并且mid+1和mid-1可以加快搜索;
  • 当二分查找需要满足一些条件时,将每次都不对mid进行+1或者-1的激进式的取边界,这样比较稳妥,不容易排除掉正确答案,而且最后都必须归结为(i, i+1)上的形式上,所以这就要求while里判定条件为 r – l >= 2 方可以进行循环,也即 l < r – 1,最后逐个判断一下l和r就可以。
    原文作者:rebornyp
    原文地址: https://blog.csdn.net/rebornyp/article/details/79531786
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞