当数组中有重复元素的时候,我们找到数组中的第一个出现的给定值的元素:
func TwoSort(arr []int,val int) int {
l :=0
r :=len(arr) - 1
for l <=r {
mid :=(l + r) / 2
if arr[mid] > val {
r = mid -1
}else if arr[mid] < val {
l = mid + 1
}else {
if mid == 0||arr[mid-1]!=val { //精华就是这一步,我们把arr[mid]=val
//分为2种情况,第一种是mid直接到第一个
return mid //或者是mid的前面的一个不等于val
}else {
r = mid - 1
}
}
}
return -1
}
找出数组中符合给定值的最后一个值的下标:
func TwoSort(arr []int,val int) int {
l :=0
r :=len(arr) - 1
for l <=r {
mid :=(l + r) / 2
if arr[mid] > val {
r = mid -1
}else if arr[mid] < val {
l = mid + 1
}else {
if (mid == len(arr) - 1)||(arr[mid+1]!=val){ //精华就是这一步,我们把arr[mid]=val
//分为2种情况
return mid
}else {
l = mid + 1
}
}
}
return -1
}
查找最后一个值小于或者等于给定值的元素:
func TwoSort(arr []int,val int) int {
l :=0
r :=len(arr) - 1
for l <=r {
mid :=(l + r) / 2
if arr[mid] > val {
r = mid -1
}else { //当这个值为最后一个值或者是这个值的后一个大于给定值
if (mid == len(arr) - 1)||(arr[mid+1] > val){ //精华就是这一步
return mid
}else {
l = mid + 1
}
}
}
return -1
}
当查找第一个值大于或者等于等于给定值当的元素:
func TwoSort(arr []int,val int) int {
l :=0
r :=len(arr) - 1
for l <=r {
mid :=(l + r) / 2
if arr[mid] >= val {
if mid == 0 ||arr[mid-1] < val {
return mid
}else {
r = r - 1
}
}else {
l = mid + 1
}
}
return -1
}
这里有一个变种问题,就是我们给的数组是一个循环的数组,比如说[4,5,6,1,2,3],那么我们怎么实现一个普通的二分查找呢?
func TwoSort(arr []int,val int) int {
l :=0
r :=len(arr) - 1
for l <=r {
mid :=(l + r) / 2
if arr[mid] == val {
return mid
}
//如果首元素大于mid,说明后半部分是有序的
if arr[l] >arr[mid] {
if arr[mid] < val && val <=arr[r] {
l = mid +1
}else {
r =mid - 1
}
//下面说明前半部分是有序的
}else {
if arr[l] <= val && val < arr[mid] {
r = mid - 1
}else {
l = mid + 1
}
}
}
return -1
}