首先,从题目可以看出,对于大部分的开发者来说,这是一个基础得不能再基础的题目了,所以,知道如何求解以及对求解过程完全掌握的话,可以不用往下看了,如果对于这个问题希望能复习一下,或者不太了解的话,可以接着往下看。我写的实在也有浪费阅读者时间的嫌疑,而目的也只是希望用清晰明确的语言将这些简单的题目讲解清楚,来提升表达方面的能力。
题目描述
给定一个无序的数组,求出这个数组中的最大值与最小值。
解题思路
比方说,有一个无序的数组[3,5,7,2],可以看出,这个数组中最大值是2,最小值是7。
如何求呢? 先求最大值,我们可以先声明一个变量为最大值,这个变量初始值为数组中的第一个元素,然后循环遍历这个数组,将目前这个最大值与当前遍历的元素进行比较,如果当前的元素比这个变量大,则更新这个最大值为当前元素的值。
代码实现
使用swift代码,注意此时代码中元素的类型应该使用泛型,返回类型应该为optional(可选型),因为数组如果为空的话,并不存在最大值与最小值。如下代码为求数组中的最大值。
func findMax<T:Comparable>(_ array: [T]) ->T? {
guard var max = array.first else { return nil }
for element in array.dropFirst() {
if(element > max){
max = element
}
}
return max
}
复制代码
以[3,5,7,2]这个数组为例,进行具体的讲解,首先,假设数组中的第一位3为最大值,先与后面的5开始比较,5比较大,此时更新5为最大值,再与后面的7比较,7又比5大,更新7位最大值,7在与2进行比较,7比2大,保持不变,循环结束,7为数组中的最大值。
求最小值同样思路:
func findMin<T:Comparable>(_ array: [T]) ->T? {
guard var min = array.first else { return nil }
for element in array.dropFirst() {
if(element < min){
min = element
}
}
return min;
}
复制代码
另外,在语言的标准库中,也可能封装好了求解最大值,最小值的函数,可以直接使用。
let array = [4,12,56,32,65,2,3,6]
array.min() // 求最小值 返回2
array.max() // 求最大值 返回65
复制代码
如何把求最大值与最小值封装到一个函数里呢?在swift中,可以使用元组同时返回最大值与最小值。
示例代码:
func findMaxMin<T:Comparable>(_ array:[T]) ->(min: T,max:T)? {
guard var min = array.first else { return nil }
var max = min
let start = array.count % 2 // 如果个数为单数,则从index = 1开始遍历
for i in stride(from: start, to: array.count, by: 2) {
let pair = (array[i],array[i+1])
if(pair.0 > pair.1){
if pair.0 > max {
max = pair.0
}
if pair.1 < min {
min = pair.1
}
} else {
if pair.1 > max {
max = pair.1
}
if pair.0 < min {
min = pair.0
}
}
}
return (min, max)
}
复制代码
代码的整体逻辑并不难理解,以数组[3,7,2,5,9] 为例进行讲解。
首先取首元素作为最大值与最小值,然后判断数组元素的个数是单数还是双数,如果是单数,则遍历数组从index = 1开始,这是因为数组进行遍历时,是成对进行遍历。
数组[3,7,2,5,9]元素个数是单数,第一次取7,2组成元组(7,2),然后7 与2 进行比较,7比2大,所以7与设定为最大值的首元素进行比较,7比3大,7取代3成为最大值。然后2与同样设定为最小值的3进行比较,2比3小,2取代3成为最小值。
继续下一组5,9组成元组,先组内进行比较,9比5大,所以用9与暂时的最大值7进行比较,9比7大,9取代7成为最大值。然后用5与暂时的最小值2进行比较,2比5小,2依旧保持为当前的最小值。
循环结束,当前的最小值2,最大值9,组成元组(2, 9),作为函数的返回值进行输出。自此,函数运行结束。
在有些语言中或许没有类似元组的数据结构,也可以使用数组,数组的第一个元素存储最小值,第二个元素存储最大值。也可以使用map,进行键值存储后作为函数返回值输出。
时间复杂度分析
循环遍历了数组一遍,并取出元素的每个元素进行了最大或最小的比较,所以这个算法的时间复杂度是O(n)。