在有序数组中寻找num,我们采用二分查找的方法,更加便捷
假如一个有序数组 1,2,3,4,5,6,7,8,9
查找8
则令第一个数坐标first=0
最后一个数坐标last = 8
中间坐标middle=(first+last)/2
然后判断坐标为middle的数(5)和num的大小
如果比middle大,则num一点在其右边,反之亦然
此例中num要大于middle,则继续二分,middle右边的数即可
last在其右边,不需要改变,只用改变first即可,first= middle+1
package main
import "log"
func main() {
arr := []int{1, 2, 2, 2, 6, 7, 7, 8, 10, 11, 11, 12}
log.Println(arr)
value := 9
exist(arr, value, 0, len(arr)-1)
}
//采用递归的方式进行二分
func exist(arr []int, value, frist, last int) {
if last < frist {
log.Println("无")
return
}
middle := (frist + last) / 2
//如果middle要大所以value在左边
if arr[middle] > value {
exist(arr, value, frist, middle-1)
//如果middle要小所以value在右边
} else if arr[middle] < value {
exist(arr, value, middle+1, last)
} else {
log.Println("8所在的位置:", middle)
}
}
//for循环解决,直到first和last合并到一个位置并进行判定完后结束
func exist02(arr []int, num int) bool {
if arr == nil || len(arr) == 0 {
return false
}
l := 0
r := len(arr) - 1
m := 0
for l <= r {
m = l + (r-l)/2 //防止r+l得到的值溢出,产生不必要的麻烦
//m = l + (r-l)>>1 //位运算
//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最左的位置同样的道理
package main
import "log"
func main() {
arr := []int{1, 5, 9, 13, 25, 46}
search := 6
log.Println(arr)
log.Println(moreEqualMostLeft(arr, search))
}
func moreEqualMostLeft(arr []int, num int) int {
if arr == nil || len(arr) < 1 {
return -1
}
l := 0
r := len(arr) - 1
m := 0
ans := -1
for l <= r {
m = l + (r-l)>>1
if arr[m] > num {
ans = m
r = m - 1
} else {
l = m + 1
}
}
return ans
}
寻找数组中<=num最左的位置同样的道理
package main
import "log"
func main() {
arr := []int{1, 5, 9, 13, 25, 46}
search := 6
log.Println(arr)
log.Println(lessEqualMostRight(arr, search))
}
func lessEqualMostRight(arr []int, num int) int {
if arr == nil || len(arr) < 1 {
return -1
}
l := 0
r := len(arr) - 1
m := 0
ans := -1
for l <= r {
m = l + (r-l)>>1
if arr[m] < num {
ans = m
l = m + 1
} else {
r = m - 1
}
}
return ans
}
时间复杂度都为logN