题目:
有⼀个已经排好序的整数序列(升序,⽆重复项),序列中可能有正整数、负整数或者0,请 ⽤你认为最优的⽅法求序列中绝对值最⼩的数。**_要求不能使⽤顺序⽐较的⽅法(时间复杂
度需要⼩于
O(n)
),不能使⽤内置查找函数,
_**
可以⽤任何语⾔实现。 输⼊:⼀个有序的
整数序列。 输出:绝对值最⼩的数
思路:
序列有三种情况:
1.所有的值小于等于0:
绝对值最小的数为序列最右边的数, 如:[-3,-2,-1]
2.所有值大于0:
绝对值最小的数为序列最左边的数, 如:[1,2,3]
3. 序列中既包含负数又包含正数
绝对值最小的数为负数和正数交接处的 负数或正数, 如 [-3,-2,1,2,3]
这种情况,先用二分查找,查找出正负数交接的索引,然后比较正负数交接处两个数组的绝对值即可。
代码:
go:
func main() {
fmt.Println(minAbs([]int{-3, -2, -1}))
fmt.Println(minAbs([]int{1, 2, 3}))
fmt.Println(minAbs([]int{-6, -3, -2, -1, 8}))
}
func minAbs(s []int) int {
//所有的值小于等于0, 绝对值最小的为最右边的元素,如[-3,-2,-1]
if s[len(s)-1] <= 0 {
return s[len(s)-1]
}
//所有值大于等于0,绝对值最小的为最左边的元素,如[0,1,2,3]
if s[0] >= 0 {
return s[0]
}
//二分查找,找出正负数交接
start := 0
end := len(s) - 1
for {
middle := (start + end) / 2
if s[middle] == 0 {
return 0
} else if s[middle] > 0 {
if s[middle-1] < 0 {
if abs(s[middle]) < abs(s[middle-1]) {
return s[middle]
}
return s[middle-1]
} else {
end = middle - 1
}
} else {
if s[middle+1] > 0 {
if abs(s[middle]) < abs(s[middle+1]) {
return s[middle]
}
return s[middle+1]
} else {
start = middle
}
}
}
}
func abs(i int) int {
if i < 0 {
return -i
}
return i
}