假设我有一个连续数据和连续空值的数组,例如:
0, 3, 1, 2, null, null, null
如何使用二元搜索思想查找第一个null元素的索引?
答案 0 :(得分:4)
与常规二进制搜索相同,只处理NULL值,如值无穷大(max int)和其他所有值,如值0.这样,数组看起来像
0, 0, 0, 0, MAX_INT, MAX_INT, MAX_INT
此时对其上的第一个MAX_INT运行正常二进制搜索
答案 1 :(得分:1)
按如下方式进行二元搜索:
null
,二分法搜索到右边null
时,请检查左侧的元素
null
,则左侧二进制搜索null
(或者左边没有元素,因为我们已经在最左边的元素),我们找到了第一个null
的索引一些简单的伪代码:
int search(start, end):
// terminating check - should always be the first null
if start == end
// sanity check - make sure it's correct
assert(input[start] == null && (start == 0 || input[start-1] != null))
return start
mid = (start+end)/2
if input[mid] != null
return search(mid, end) // search right
else if mid == 0 || input[mid-1] != null // check element to left
return mid // found
else
return search(start, mid) // search left
答案 2 :(得分:0)
这是用Go编写的示例解决方案,具有O(log(n))时间复杂度:
package main
import "fmt"
func findIn(array []int) {
fmt.Printf("%v ", array)
if len(array) == 0 {
fmt.Println("Not Found")
return
}
for low, high, mid := 0, len(array), len(array)/2; ; {
// terminate search when high meets mid
if high-mid == 1 {
if array[mid] == -1 {
fmt.Println(mid)
return
}
if high == len(array) {
fmt.Println("Not Found")
return
}
fmt.Println(high)
return
}
// search lower half if middle is -1, otherwise search upper half
if array[mid] == -1 {
high = mid
mid = low + (mid-low)/2
} else {
low = mid
mid = mid + (high-mid)/2
}
}
fmt.Println()
}
func main() {
findIn([]int{})
findIn([]int{8})
findIn([]int{-1})
findIn([]int{8, -1, -1, -1})
findIn([]int{8, 9, 7, -1, -1, -1})
findIn([]int{8, 9, 7, 6, 5, 4, -1, -1})
}
输出:
[] Not Found
[8] Not Found
[-1] 0
[8 -1 -1 -1] 1
[8 9 7 -1 -1 -1] 3
[8 9 7 6 5 4 -1 -1] 6
请随时提出更好/更短的解决方案。
答案 3 :(得分:0)
O(n)的简单蛮力在这里可能是理想的,因为在划分和征服集合时,它同样可能会错过第一次出现的Null。