一 问题
碰到一个好玩的题目,要求只比较1.5n
次,就要求出n
个元素数组中的最大值和最小值。
二 问题分析
就一般的全遍历方法来说,n个元素数组要得到最大值和最小值,就要比较2*n
次,因为得到最小值需要比较n
次,得到最大值也需要比较n
次,这样得到最大值和最小值就需要比较2*n
次了。
想要只比较1.5n
次,可以一次拿出两个数进行比较,然后一次比较三次,这样下来,总共比较的次数就是n / 2 * 3 = 1.5n
,正好。
1.5n
次比较的思路是:
- 取出两个数,这两个数之间先比较一次,产生大者
tmax
和小者tmin
。 - 大者
tmax
和记录的最大值max
比较一次,如果tmax > max
,则tmax
替代原max
,成为最大值 - 小者
tmin
和记录的最大值min
比较一次,如果tmin < min
,则tmin
替代原min
,成为最小值
这就是一次比较:取两个数,比较三次,得出最大值和最小值。
三 代码
#include <bits/stdc++.h>
using namespace std;
void find_max_min(int num[], int len);
#define MIN -1
#define MAX 65535
int main(void)
{
int num[10] = {2, 4, 5, 6, 8, 3, 7, 1, 9, 10};
find_max_min(num, 10);
system("pause");
return 0;
}
void find_max_min(int num[], int len)
{
int i, j; // 一次取两个数的游标
int max = MIN;
int min = MAX;
int count = 0; // 计算比较的次数
int tmax, tmin;
i = 0;
j = len - 1;
while (i <= j)
{
if (num[i] < num[j]) // 两个数之间先比一次
{
tmax = num[j];
tmin = num[i];
count++;
}
else
{
tmax = num[i];
tmin = num[j];
count++;
}
if (min > tmin) //小的数和最小者比较一次
{
min = tmin;
}
if (max < tmax) //大的数和最大者比较一次
{
max = tmax;
}
count += 2; //上面的两次比较
i++; //左游标右移一位
j--; // 右游标左移一位
}
cout << "The max number is: " << max << endl;
cout << "The min number is: " << min << endl;
cout << "The count number is: " << count << endl;
}
运行得到的结果为:
参考文献
[1] 梦想与坚持. 笔试题&面试题:给定n个数,要求比较次数1.5n同时找出最大值和最小值. CSDN博客. 2014.08.
https://blog.csdn.net/laoniu_c/article/details/38468167