引入:在二分查找中,当存在多个数相同时,返回与目标相匹配的坐标值一般是不确定的。所以以下代码实现当存在多个数相同时,能够让二分查找返回目标值的最左坐标或者最右坐标。

返回值:目标的坐标,当没有匹配值时返回-1。

public class Demo {
  	// 多个数和target相同时,不确定返回的坐标位置
    public int findNonCertain(int[] ns, int target) {
        int left = 0, right = ns.length;

        while (left < right) {
            int mid = left + (right - left) / 2;
            if (ns[mid] == target) return mid;
            else if (target > ns[mid]) left = mid + 1;
            else right = mid;
        }

        return -1;
    }
  	// 多个数和target相同时,返回最左边匹配的坐标
    public int findLeft(int[] ns, int target) {
        int left = 0, right = ns.length;

        while (left < right) {
            int mid = left + (right - left) / 2;
            if (target == ns[mid]) right = mid;
            else if (target < ns[mid]) right = mid;
            else left = mid + 1;
        }

        if (left == ns.length || ns[left] != target) return -1;

        return left;
    }
  	// 多个数和target相同时,返回最右边匹配的坐标
    public int findRight(int[] ns, int target) {
        int left = 0, right = ns.length;

        while (left < right) {
            int mid = left + (right - left) / 2;

            if (target == ns[mid]) left = mid + 1;
            else if (target > ns[mid]) left = mid + 1;
            else right = mid;
        }

        if (left == 0) return -1;

        return target == ns[left - 1] ? left - 1 : -1;
    }


    @Test
    public void r1() {
        int[] ns = {1, 2, 2, 2, 4};
        int target = 2;
        System.out.println(Arrays.toString(ns));
        System.out.println("不确定二分查找:" + findNonCertain(ns, target));
        System.out.println("左二分查找:" + findLeft(ns, target));
        System.out.println("右二分查找:" + findRight(ns, target));
    }

}