/**
* 找到目标值的右侧边界,同上面一样,搜索区间都是左闭右开
*
* @param arr 输入数组
* @param target 要查找的值
* @return 找到目标值的右边界
*/publicstaticintrightBinarySearch(int[] arr,int target){int left =0;int right = arr.length;int mid =0;while(left < right){
mid = left +((right - left)>>1);if(arr[mid]== target){
left = mid+1;// 与左侧二分查找的区别!}elseif(arr[mid]> target){
right = mid;}elseif(arr[mid]< target){
left = mid +1;}}return left-1;// 与左侧二分查找的区别!}
2.5 左右侧边界合并终极版(个人还是倾向分开记忆)
publicintboundBinarySearch(int[] nums,int target){int left =0;int right = nums.length -1;int mid =0;while(left <= right){
mid = left +(right - left)/2;if(nums[mid]< target){
left = mid +1;}elseif(nums[mid]> target){
right = mid -1;}elseif(nums[mid]== target){// 别返回,锁定左侧边界
right = mid -1;}}// 左侧:最后要检查 left 越界的情况//if (left >= nums.length || nums[left] != target) {//return -1;//}//return left;// 右侧:最后要检查 right 越界的情况//if (right < 0 || nums[right] != target) {//return -1;//}//return right;}
2 插值查找
插值查找是在二分查找的基础上将mid值的计算方法做改进。其mid的计算是自适应计算。
注意:插值查找适用关键字分布比较均匀。对于关键字分布不均匀的情况下效果可能不如二分查找
m
i
d
=
l
e
f
t
−
r
i
g
h
t
2
=
l
o
w
+
1
2
(
r
i
g
h
t
−
l
e
f
t
)
\small{mid = \frac{left - right}{2} = low + \frac{1}{2}\left( {right - left} \right)}
mid=2left−right=low+21(right−left)改为:
m
i
d
=
l
o
w
+
f
i
n
d
V
a
l
−
a
r
r
[
l
e
f
t
]
a
r
r
[
r
i
g
h
t
]
−
a
r
r
[
l
e
f
t
]
(
r
i
g
h
t
−
l
e
f
t
)
\small{mid = low + \frac{{findVal - arr[left]}}{{arr[right] - arr[left]}}\left( {right - left} \right)}
mid=low+arr[right]−arr[left]findVal−arr[left](right−left)
// 二分查找int mid = left +((right - left)>>1);// 插值查找int mid = left +(right-left)*(findVal - arr[left])/(arr[right]- arr[left]);
3 斐波那契查找(黄金分割法)
斐波那契数列:{1,1,2,3,5,8,13,21,34,55…}
斐波那契数列性质:
F
[
k
]
=
F
[
k
−
1
]
+
F
[
k
−
2
]
\small{F[k]=F[k-1]+F[k-2]}
F[k]=F[k−1]+F[k−2]
斐波那契查找原理类似与二分查找。主要是改变mid值,mid位于黄金分割点附近,即
m
i
d
=
l
o
w
+
F
[
k
−
1
]
−
1
\small{mid=low+F[k-1]-1}
mid=low+F[k−1]−1。其中F代表斐波那契数列。