1、二分搜索的模板。
算法面试中,如果需要优化O(n)的时间复杂度,那么只能是O(logn)的二分法。
注意二分法大多数情况都是适用于排序数组。自己写二分的时候经常忘记写return -1;
http://www.lintcode.com/zh-cn/problem/first-position-of-target/
模板有四点注意:
1)start+1<end;(最后会得到start,end两项)
2) mid=start+(end-start)/2;//为了防止start+end超出计算机表示范围
3) A[mid]==,<,>;
4) A[start]A[end]?target。(找第一个元素就是把A[start]放在前面,否则end放在if前面)
func binarySearch (nums []int, target int) int {
// write your code here
if len(nums) == 0 {
return -1
}
start := 0
end := len(nums) - 1
for start + 1 < end {
mid := start + (end - start) / 2
if nums[mid] == target {
end = mid
}else if nums[mid] < target {
start = mid
} else {
end = mid
}
}
if nums[start] == target {
return start
}
if nums[end] == target {
return end
}
return -1
}
2、使用二分搜索解决问题以及变种问题
找第一个位置&&找最后一个位置。
2.1搜索区间
http://www.lintcode.com/zh-cn/problem/search-for-a-range/
思路:使用二分搜索分别找到第一个等于target的元素和最后一个等于target的元素。(使用if判断一定要有对应的else,逻辑才会正确,不然会出错)
/**
* @param A: an integer sorted array
* @param target: an integer to be inserted
* @return: a list of length 2, [index1, index2]
*/
func searchRange (A []int, target int) []int {
// write your code here
if len(A) == 0 {
return []int{-1, -1}
}
// start position
res := []int{-1, -1}
start := 0
end := len(A) - 1
for start + 1 < end {
mid := start + (end -start) / 2
if A[mid] == target {
end = mid
} else if A[mid] < target {
start = mid
} else {
end = mid
}
}
if A[start] == target {
res[0] = start
}else if A[end] == target {
res[0] = end
} else {
res[0] = -1
}
// end position
start = 0
end = len(A) - 1
for start + 1 < end {
mid := start + (end -start) / 2
if A[mid] == target {
start = mid
} else if A[mid] < target {
start = mid
} else {
end = mid
}
}
if A[end] == target {
res[1] = end
} else if A[start] == target {
res[1] = start
} else {
res[1] = -1
}
return res
}