查找一个序列的最大值和最小值

        这个问题,解法比较多,先说下普通的想法,先设定最大值和最小值都为序列中第一个元素值,在一个循环内,每次循环都和当前最大值和最小值来比较更新,这样就需要2N-2次比较了;

  再进一步,如果先查找最大值,则需N-1次比较,再查找最小值,则需N-2次比较,总共是2N-3次比较,比上一方法少了1次。

  这些做法都是每次取1个数来比较,比较次数为O(2N)。接下来,我们把情况扩展到每次取多于1个数,先试试看每次取2个数,即N-2个数的解,对N个数求解。当N=1时,最大值和最小值就是第1个元素值;当N=2时,最大值和最小值就是第1个元素和第2个元素的最大值和最小值;考察X[N-2]和X[N-1],同时令前N-2个数的解是MAX和MIN,易见,做3次比较便能得出新的最大值和最小值,首先比较X[N-2]和X[N-1],然后将其中大数同MAX比较,小数同MIN比较,这样一来,大约需O(3N/2)次比较即可,而不是先前的O(2N)次。那么,是不是每次取3个或4个数能更进一步减少总共的比较次数呢?可以证明,每次取多于2个数来比较时,总共所需次数和取2个元素来比较是一样的。

  这是用java实现的每次取两个元素的算法,代码如下。。

package test;

public class Get_max_min {

	public static void main(String[] args) {
		int[] jishu = new int[] { 9, 10, 44, 22, 53, 10, 23, 56, 77, 16, 60 };//测试奇数个数
		int[] oushu = new int[] { 10, 44, 22, 53, 10, 23, 56, 77, 16, 60 };//测试偶数个数
		int[] a = get_max_min(jishu);
		int[] b = get_max_min(oushu);
		System.out.println("奇数个,min:" + a[0] + ",max:" + a[1] + ",total:"
				+ jishu.length + ",times:" + a[2]);
		System.out.println("偶数个,min:" + b[0] + ",max:" + b[1] + ",total:"
				+ oushu.length + ",times:" + b[2]);
	}
	/**查找序列(数组)中的最大值,最小值,
	 * param int[],要查找的序列
	 * return int[],返回这两个值和查找的次数组成的数组
	 */
	public static int[] get_max_min(int[] a) {
		int[] result = new int[3];
		int n = a.length;
		int tmax, tmin, i, count = 0;
		result[0] = result[1] = a[0];
		for (i = 1; i < n - 1; i += 2) {
			if (a[i] < a[i + 1]) {
				tmax = a[i + 1];
				tmin = a[i];
			} else {
				tmin = a[i + 1];
				tmax = a[i];
			}
			count += 3;
			if (result[0] > tmin)
				result[0] = tmin;
			if (result[1] < tmax)
				result[1] = tmax;
		}
		if (i == n - 1) {
			count += 2;
			if (result[0] > a[n - 1])
				result[0] = a[n - 1];
			if (result[1] < a[n - 1])
				result[1] = a[n - 1];
		}
		result[2] = count;
		return result;
	}

}

执行后结果如下:

由前面分析可知,当N为奇数时,总共比较次数为3/2*(N-1);当N为偶数时,总共比较次数为3N/2-1,时间复杂度为0(3N/2)。 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值