算法6 二分查找
在有序数组中确定num存在还是不存在
public static boolean exist(int[] arr, int num) {
if (arr == null || arr.length == 0) {
return false;
}
int l = 0, r = arr.length - 1, m = 0;
while (l <= r) {
m = (l + r) / 2;
if (arr[m] == num) {
return true;
} else if (arr[m] > num) {
r = m - 1;
} else {
l = m + 1;
}
}
return false;
}
在有序数组中找到>=num的最左边的位置(数组中不一定有num)
// 有序数组中找>=num的最左位置
public static int findLeft(int[] arr, int num) {
int l = 0, r = arr.length - 1, m = 0;
int ans = -1;
while (l <= r) {
// m = (l + r) / 2;
// m = l + (r - l) / 2;
m = l + ((r - l) >> 1);
if (arr[m] >= num) {
ans = m;//提前存下来
r = m - 1;
} else {
l = m + 1;
}
}
return ans;
}
在有序数组中找到<=num的最左=右边的位置(数组中不一定有num)
// 有序数组中找<=num的最右位置
public static int findRight(int[] arr, int num) {
int l = 0, r = arr.length - 1, m = 0;
int ans = -1;
while (l <= r) {
m = l + ((r - l) >> 1);
if (arr[m] <= num) {
ans = m;//提前存下来
l = m + 1;
} else {
r = m - 1;
}
}
return ans;
}
mid = l + (r - l) / 2;
不使用mid=(l+r)/2,是因为当l和r很大,到达int_value_max时间,有溢出的风险,而 l + (r - l) / 2先减了一下,所以规避了溢出的风险。
public static int findPeakElement(int[] arr) {
int n = arr.length;
if (arr.length == 1) {
return 0;
}
if (arr[0] > arr[1]) {
return 0;
}
if (arr[n - 1] > arr[n - 2]) {
return n - 1;
}
int l = 1, r = n - 2, m = 0, ans = -1;
while (l <= r) {
m = (l + r) / 2;
if (arr[m - 1] > arr[m]) {
r = m - 1;
} else if (arr[m] < arr[m + 1]) {
l = m + 1;
} else {
ans = m;
break;
}
}
return ans;
}
}