求一个数组中的最大值和最小值,要求将比较次数减小至3N/2
2016-08-10 10:06
239 查看
1、取双元素法
每次取两个元素,用较小的和最小值比较,用较大的和最大值比较,那么总共会取N/2次,每取一次会进行三次比较,第一次比较当前两个元素,第二次较小的和当前最小值比较,
第三次较大的和当前最大值比较,总的比较次数便是:3N/2。需要注意的是:
(1)输入数组的合法性检查(空指针或者数组的长度为0);
(2)边界检查:输入数组只有1个元素,那么最小值和最大值均为该元素;
(3)初始化最小值、最大值为第一个和第二个元素中的较小值和较大值,从第三个元素开始扫描,只要i < array.length则循环,不过要注意的是数组中的元素个数为奇数时,i最后会指向最后一个元素,即i = array.length - 1,这时就拿它去更新最小值和最大值,然后退出循环。
private static void MinAndMaxInArrayCore(int[] array) {
if(array == null || array.length == 0)
return;
int n = array.length;
int max_value, min_value;
if(n == 1) {
min_value = max_value = array[0];
System.out.println(min_value + " " + max_value);
return;
}
if(array[0] >= array[1]) {
min_value = array[1];
max_value = array[0];
}
else {
min_value = array[0];
max_value = array[1];
}
int i = 2;
while(i < n) {
if(i == n - 1) {
if(array[i] < min_value)
min_value = array[i];
else if(array[i] > max_value)
max_value = array[i];
break;
}
if(array[i] < array[i + 1]) {
if(array[i] < min_value)
min_value = array[i];
if(array[i + 1] > max_value)
max_value = array[i + 1];
}
else {
if(array[i] > max_value)
max_value = array[i];
if(array[i + 1] < min_value)
min_value = array[i + 1];
}
i += 2;
}
System.out.println(min_value + " " + max_value);
}
2、分治法
将数组分成两半,分别求出左边的最小值和最大值,右边的最小值和最大值,然后在求得总的最小值和最大值。
注意输入的参数包括:数组,开始坐标start,结束坐标end,和用来保存最小值和最大值的引用类型。递归头是:
当start == end时,mm.minValue = mm.maxValue = arrar[start]
private static void minAndMaxInArray(int[] array, int start, int end, MinAndMax mm) {
if(start == end) {
mm.minValue = mm.maxValue = array[start];
return;
}
int n = end - start + 1;
n >>= 1;
minAndMaxInArray(array, start, start + n - 1, mm);
int min_left = mm.minValue, max_left = mm.maxValue;
minAndMaxInArray(array, start + n, end, mm);
int min_right = mm.minValue, max_right = mm.maxValue;
mm.minValue = min_left < min_right ? min_left : min_right;
mm.maxValue = max_left > max_right ? max_left : max_right;
}
每次取两个元素,用较小的和最小值比较,用较大的和最大值比较,那么总共会取N/2次,每取一次会进行三次比较,第一次比较当前两个元素,第二次较小的和当前最小值比较,
第三次较大的和当前最大值比较,总的比较次数便是:3N/2。需要注意的是:
(1)输入数组的合法性检查(空指针或者数组的长度为0);
(2)边界检查:输入数组只有1个元素,那么最小值和最大值均为该元素;
(3)初始化最小值、最大值为第一个和第二个元素中的较小值和较大值,从第三个元素开始扫描,只要i < array.length则循环,不过要注意的是数组中的元素个数为奇数时,i最后会指向最后一个元素,即i = array.length - 1,这时就拿它去更新最小值和最大值,然后退出循环。
private static void MinAndMaxInArrayCore(int[] array) {
if(array == null || array.length == 0)
return;
int n = array.length;
int max_value, min_value;
if(n == 1) {
min_value = max_value = array[0];
System.out.println(min_value + " " + max_value);
return;
}
if(array[0] >= array[1]) {
min_value = array[1];
max_value = array[0];
}
else {
min_value = array[0];
max_value = array[1];
}
int i = 2;
while(i < n) {
if(i == n - 1) {
if(array[i] < min_value)
min_value = array[i];
else if(array[i] > max_value)
max_value = array[i];
break;
}
if(array[i] < array[i + 1]) {
if(array[i] < min_value)
min_value = array[i];
if(array[i + 1] > max_value)
max_value = array[i + 1];
}
else {
if(array[i] > max_value)
max_value = array[i];
if(array[i + 1] < min_value)
min_value = array[i + 1];
}
i += 2;
}
System.out.println(min_value + " " + max_value);
}
2、分治法
将数组分成两半,分别求出左边的最小值和最大值,右边的最小值和最大值,然后在求得总的最小值和最大值。
注意输入的参数包括:数组,开始坐标start,结束坐标end,和用来保存最小值和最大值的引用类型。递归头是:
当start == end时,mm.minValue = mm.maxValue = arrar[start]
private static void minAndMaxInArray(int[] array, int start, int end, MinAndMax mm) {
if(start == end) {
mm.minValue = mm.maxValue = array[start];
return;
}
int n = end - start + 1;
n >>= 1;
minAndMaxInArray(array, start, start + n - 1, mm);
int min_left = mm.minValue, max_left = mm.maxValue;
minAndMaxInArray(array, start + n, end, mm);
int min_right = mm.minValue, max_right = mm.maxValue;
mm.minValue = min_left < min_right ? min_left : min_right;
mm.maxValue = max_left > max_right ? max_left : max_right;
}
相关文章推荐
- 算法8:一个整数数组里怎么同时找最大和最小的数,尽量优化比较次数
- 关于在一个无序数组中的数求最大值和最小值的最小比较次数
- 试着用最小的比较次数去寻找数组中的最大值和最小值。
- 【1】 设一个长度为10的整型数组,  0)要求每个元素的值通过scanf输入,输入完成后,  1)请顺序输出这些整数,  2)请倒序输出这些整数,  3)输出这些数中的最大值,最小值
- 设计一个最优算法来查找一n个元素数组中的最大值和最小值。已知一种需要比较2n次的方法,请给一个更优的算法。
- 笔试题&面试题:给定n个数,要求比较次数1.5n同时找出最大值和最小值
- 面试题--尽可能的减少求一个数组的最大最小值的比较次数
- 求数组中最大值和最小值 以及 求数组中最大值和次大值 最小比较次数
- [面试题]用最少的比较次数找出一个数组中的最大值和次大值
- 设定二维整数数组B[0..m-1,0..n-1]的数据在行,列方向上都按从小到大的顺序排序,且整形变量x中的数据在B中存在。设计一个算法,找出一对满足B[i][j]=x的I,j值,要求比较次数不超过m
- 最大最小值:给n个实数,求它们之中的最大值和最小值,要求比较次数尽量小。
- 设一个长度为10的整型数组, 0)要求每个元素的值通过scanf输入,输入完成后, 1)请顺序输出这些整数, 2)请倒序输出这些整数, 3)输出这些数中的最大值, 4)输出这些数中的最小值
- [BUC-2.10]利用分治的思想求无序数组中的最大值和最小值以及求第二大的值(分治的思想可以使得比较的次数1.5N-2)
- 最大最小值:给n个实数,求它们之中的最大值和最小值,要求比较次数尽量小。
- [算法导论]在一个数组中寻找最大值和最小值所需要进行比较的次数
- 函数调用输出一个一维数组中的最大值、最小值、全部元素的和,并将此数组中的值按逆序重新存放。
- 定义一个二维数组,写函数来实现对该二维数组求最大值。(要求,用行指针为函数形参)
- 同时寻找一个数组中的最大元素和最小元素--你会有所收获
- 求一个数组中重复元素出现最多值,最大的元素及出现次数,次数相同时,取最大值,优先考虑次数
- KMP算法 —— next 数组的应用 --- 前缀中最小循环节,最大重复次数