Binary Search
二分查找(递归与非递归)
public class BinarySearch {
private BinarySearch() {
}
//非递归二分查找
public static <T extends Comparable<? super T>> int binarySearch(T[] arr, T key) {
int low = 0;
int high = arr.length - 1;
//查找arr[low...high]是否存在key
while (low <= high) {
int mid = low + (high - low) / 2;
if (arr[mid].compareTo(key) == 0) {
return mid;
}
if (arr[mid].compareTo(key) > 0) { //arr[low...mid-1]是否存在key
high = mid - 1;
} else { //arr[mid+1...high]是否存在key
low = mid + 1;
}
}
return -1;
}
/*对于mid溢出问题:
* 1.long c=a+b;
* int mid=c/2;
* 2.int mid=(a+b)>>>1; //这是运用a+b不会溢出,是因为int是32位,但是第31位是符号为所以进行位运算时不会溢出
* 3.int mid=a&b+(a^b)>>1;
* 目的:两个二进制数,对应位置进行相加,求出每项的项系数,也就是每位结果。
* 1.对应位相等,即同为1,或同为0
* 2.对应为不同,其中一个为1,另一个为0
* 假设先不考虑进位,a+b = 2110211.
* 去找规律,发现,情况为2时,相加总为1,相当于异或运算。对于情况1,异或运算总为0.
* 再去找规律,发现,情况为1时,两数相与的结果就是两数相加的一半。
*
* a:1100110
* b:1010101
* ^:0110011 0 1 4 5 找到了这些项的系数
* &:1000100 2 3 6 找到了这些项的系数
* 但上面这个与运算得出来的并不是真正的项系数,而是对应位置项系数的一般。所以 * 2后得
* :2000200(先不考虑进位)
* 所以sum = (a & b) * 2 + (a ^ b)
* sum / 2 = (a & b) + (a ^ b) / 2
* */
//递归二分查找
public static <T extends Comparable<? super T>> int binarySearch2(T[] arr, T key, int low, int high) {
if (low > high) {
return -1; //如果没找到就返回-1
}
int mid = low + (high - low) / 2; //数组中间下标,可能会溢出...
if (arr[mid] == key) {
return mid;
} else if (arr[mid].compareTo(key) > 0) {
return binarySearch2(arr, key, low, mid - 1);
} else {
return binarySearch2(arr, key, mid + 1, high);
}
}
}二分查找(变形)
public class BinarySerachBian {
/**
* 二分搜索
*
* @param arr
* @param target
* @param <T>
* @return
*/
public static <T extends Comparable<? super T>> int binarySearch(T[] arr, T target) {
int low = 0;
int high = arr.length - 1;
while (low <= high) {
int mid = (low & high) + ((low ^ high) >> 1);//算符优先级:单目乘除位关系,逻辑三目后赋值
if (arr[mid].compareTo(target) == 0) {
return mid;
} else if (arr[mid].compareTo(target) < 0) {
low = mid + 1;
} else {
high = mid - 1;
}
}
return -1;
}
/**
* 使用分治,查找元素在数组中第一次出现的位置,如果存在就返回相应的位置;如果不存在就返回-1;
*
* @param arr
* @param target
* @param <T>
* @return
*/
public static <T extends Comparable<? super T>> int firstFind(T[] arr, T target) {
int low = 0;
int high = arr.length - 1;
while (low < high) {
int mid = (low & high) + ((low ^ high) >> 1);
if (arr[mid].compareTo(target) < 0) {
low = mid + 1;
} else {
high = mid;
}
}
if (arr[low] == target) {
return low;
} else {
return -1;
}
}
/**
* 给定一个数组,和一个target,找出小于target的最接近target的值
*
* @param arr
* @param terget
* @param <T>
* @return
*/
public static <T extends Comparable<? super T>> int findFloor(T[] arr, T terget) {
int low = 0;
int high = arr.length - 1;
while (low <= high) {
int mid = (low & high) + ((low ^ high) >> 1);
if (arr[mid].compareTo(terget) >= 0) {
high = mid - 1;
} else {
low = mid + 1;
}
}
return high;
}
} 相关推荐
HMHYY 2020-07-28
ELEMENTS爱乐小超 2020-07-04
amazingbo 2020-06-28
alicelmx 2020-06-16
minkee 2020-06-09
逍遥友 2020-06-02
嗡汤圆 2020-05-10
whbing 2020-05-05
zhuxianfeng 2020-05-02
assastor 2020-05-01
JessePinkmen 2020-05-01
hongxiangping 2020-04-30
theta = np.zeros #theta = array,构造全为零的行向量。grad[0,j] = np.sum/len #∑term / m. return value > threshol
Kwong 2020-04-26
88483063 2020-04-23
xirongxudlut 2020-04-19