求一个数组中的最大值和最小值,要求将比较次数减小至3N/2
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;
}
- 上一篇: java中List<T>和List<?>的区别
- 下一篇: php根据源url获取主机名,协议名总结