引入:在二分查找中,当存在多个数相同时,返回与目标相匹配的坐标值一般是不确定的。所以以下代码实现当存在多个数相同时,能够让二分查找返回目标值的最左坐标或者最右坐标。
返回值:目标的坐标,当没有匹配值时返回-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));
}
}