1. 问题
给定一个数组,要求找出数组中的最大值和最小值,假设数组中的值两两各不相同
2. 思路
2.1 首元素比较法
定义变量 max
、min
, 分别将第一个元素分别赋值给这两个变量,然后依次遍历数组中的全部元素,如果比 max
大就将该元素赋值给 max
, 如果比 min
小就将该元素赋值给 min
。遍历结束 max
和 min
就分别为最大值和最小值。
2.2 分治法
分治法就是将一个规模为 n
的、难以直接解决的大问题,分割为 k
个规模较小的子问题,采取各个击破、分而治之的策略得到各个子问题的解,然后将各个子问题的解进行合并,从而得到原问题的解的一种方法。
在该题中,采用分治法时将数组两两一对分组,如果数组元素个数为奇数时,就把最后一个元素单独划分为一组,然后分别对每一组相邻的元素进行比较,小的放左边,大的放右边。然后在每一组的左边寻找最小值,每一组的右边寻找最大值。
2.3 变形分治法
将数组分为左右两部分,先求出左半部分和右半部分的最小值和最大值,然后综合起来,左右两部分的最小值就是合并后的最小值,左右两部分的最大值就是合并后的最大值。
递归执行以上过程,反复执行,直到划分区间内只剩下一个或者两个元素为止
3. 代码实现
package main
import "fmt"
func findMaxMinValueOne(a []int) (int, int) {
max := a[0]
min := a[0]
for _, v := range a {
if v < min {
min = v
}
if v > max {
max = v
}
}
return min, max
}
func findMaxMinValueTwo(a []int) (int, int) {
temp := 0
// 两两分组,将较小者放到左边,较大者放到右边
for i := 0; i < len(a); i += 2 {
if a[i] > a[i+1] {
temp = a[i]
a[i] = a[i+1]
a[i+1] = temp
}
}
max := a[0]
min := a[0]
// 在左半部分寻找最小者
for i := 0; i < len(a); i += 2 {
if a[i] < min {
min = a[i]
}
}
// 在右半部分寻找最大者
for i := 1; i < len(a); i += 2 {
if a[i] > max {
max = a[i]
}
}
// 如果数组个数为奇数个,那么最后一个元素被分为一组,需要特殊处理
if len(a)%2 == 1 {
if max < a[len(a)-1] {
max = a[len(a)-1]
}
if min > a[len(a)-1] {
min = a[len(a)-1]
}
}
return min, max
}
func main() {
arr := []int{1, 2, 4, 3, 5, 4}
min, max := findMaxMinValueOne(arr)
fmt.Println("min is ", min, "max is ", max)
min, max = findMaxMinValueTwo(arr)
fmt.Println("min is ", min, "max is ", max)
}