二分查找
找出一个有序的字符串数组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就可以。