原文发表于:
周天,深圳,大雨。
今天来看一个简单的问题,即同时求最大值和最小值,具体问题和要求如下:
求数组的最大值和最小值,要求比较次数的数量级是O(1.5n).
扫描二维码关注公众号,回复:
12272140 查看本文章
我们先来看普通的直观解法:
package main
import "fmt"
func getMinMax(a []int) (int, int){
if len(a) == 0 {
// 异常处理
}
min, max := a[0], a[0]
for _, v := range a {
if v < min {
min = v
}
if v > max {
max = v
}
}
return min, max
}
func main() {
fmt.Println(getMinMax([]int{3, 2, 4, 1, 5, 9, 6, -1}))
}
结果:-1 9
可以看到,程序中比较次数的数量级是O(2n), 在实际开发中,这样做往往是能满足要求的,而且也是直观易懂的解法,代码的可读性也较好。
我们看看上述代码的具体思路:如下图,当遍历前面两个元素后,得到min和max的值分别为2和3,在与接下来的4和1的比较中,min要比较2次, max要比较2次,总共就是4次。
然而,如果按照问题的要求,将目标的比较次数优化为O(1.5n),那该怎么着手去做呢?我们看到,如果我们先把4和1进行比较,得出较大的4和较小的1, 那么剩下的就只需要将min和1比较,将max和4比较就行,总共比较次数只有3次,减少了无用的比较,如下图:
可以看到,优化的思路就是对元素进行两两分组,比较次数从O(2n)优化到了O(1.5n),既然缕清了思路,那么代码实现就是相对简单的事情了,在此不再赘述。
本文比较简单,关键还是思路,先聊到这里。