二分查找
二分查找
从一个从小到大的序列中找寻数goal, 采用二分查找。
思路:选择两个变量,分别赋值区间的首尾;选取区间的中间值与goal相比较,如果goal较大,那么将begin = middle, 如果goal较小, 那么 end = middle;考虑到begin和end可能相等,goal会在边界被找到,那么循环条件为begin <= end
func binarySearch(arr []int, goal int) (index int) {
begin := 0
end := len(arr)-1
for ;begin <= end; {
middle := (end + begin) / 2
if arr[middle] < goal {
begin = middle
} else if arr[middle] > goal {
end = middle
} else {
return middle
}
}
return -1
}
上述思路未考虑到边界条件中这种情况。例如区间为[5, 6],goal>arr[5]的情况,此时区间此后将一直是[5,6]不会向前移动。(此种情况不会出现左边界,即goal == arr[5])
思路:当arr[middle] < goal时,begin = middle+1;当arr[middle] > goal时, end = middle or end = middle - 1。加1或减1不会使过程中出现界限被超出
func binarySearch(arr []int, goal int) (index int) {
begin := 0
end := len(arr)-1
for ;begin <= end; { //"=" 展示可能出现边界情况
middle := (end + begin) / 2
if arr[middle] < goal {
begin = middle+1
} else if arr[middle] > goal {
end = middle-1
} else {
return middle
}
}
return -1
}
二分查找中个人认为区间应该始终为左闭右闭区间。不应该使循环代码中begin,end变量来维持区间的开闭性质
func search( nums []int , target int ) int {
// write code here
low, high := 0, len(nums)-1
for ; low <= high; {
mid := low + (high-low) / 2
fmt.Println(low, high, mid)
if nums[mid] < target {
low = mid+1
} else if nums[mid] > target {
high = mid-1
} else {
j := mid-1
for ; j >= 0; j-- {
if (nums[j] != target) {
break
}
}
return j+1
}
}
return -1
}
测试用例[1, 2, 2, 3, 4],2 输出结果应为1