每日一题(22) - 寻找数组中的最大值和最小值

本文探讨如何在最少比较次数下找到数组中的最大值和最小值。通过分治法解决此问题,详细解析可在链接中查看。同时,文章也提及了当最大值重复出现时,如何处理无法找到次大值的情况,并给出具体示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目来自编程之美

题目:寻找数组中的最大值和最小值

要求:要求比较次数最少

分析:使用分治法解决,详细见点击打开链接

代码:

#include <iostream>
#include <assert.h>
using namespace std;

void FindMaxAndMin(int arr[],int nStart,int nEnd,int& nMax,int& nMin)
{
	assert(arr != NULL && nStart <= nEnd && nStart >= 0 && nEnd >= 0);
	int nLeftMax = 0;
	int nLeftMin = 0;
	int nRightMax = 0;
	int nRightMin = 0;
	if (nStart == nEnd - 1)//区间相差为1
	{
		if (arr[nStart] > arr[nEnd])
		{
			nMax = arr[nStart];
			nMin = arr[nEnd];
		}
		else
		{
			nMax = arr[nEnd];
			nMin = arr[nStart];
		}
		return;
	}
	if (nStart == nEnd)//区间相差为0
	{
		nMin = nMax = arr[nStart];
		return;
	}
	int nMid = (nStart + nEnd)/2;
	FindMaxAndMin(arr,nStart,nMid,nLeftMax,nLeftMin);
	FindMaxAndMin(arr,nMid + 1,nEnd,nRightMax,nRightMin);
	//分别比较两部分的最大值和最小值,求出整体的最大值和最小值
	nMax = max(nLeftMax,nRightMax);
	nMin = min(nLeftMin,nRightMin);
}


int main()
{
	int nMin = 0;
	int nMax = 0;
	int arr[8] = {4,-3,5,-2,-1,2,6,-2};
	FindMaxAndMin(arr,0,7,nMax,nMin);
	cout<<"Max: "<<nMax<<endl;//6
	cout<<"Min: "<<nMin<<endl;//-3

	int arr1[8] = {4,-3,5,-11,4,-2,5,-2};
	FindMaxAndMin(arr1,0,7,nMax,nMin);
	cout<<"Max: "<<nMax<<endl;//5
	cout<<"Min: "<<nMin<<endl;//-11

	int arr2[8] = {-3,-5,-8,-2,-11,-12,-13,-1};
	FindMaxAndMin(arr2,0,7,nMax,nMin);
	cout<<"Max: "<<nMax<<endl;//-1
	cout<<"Min: "<<nMin<<endl;//-13
	system("pause");
	return 1;
}

题目来自编程之美

题目:寻找数组中的最大值和次大值

要求:要求比较次数最少

分析:使用分治法解决,详细见点击打开链接

注意:如果最大值在序列中重复出现,无法找到次大值。

举例:如序列:4,-3,5,-11,4,-2,5,-2, 最大值5出现了两次,此时算法输出5和5,而不是5,4。

代码:

#include <iostream>
#include <assert.h>
using namespace std;

void FindMaxAndSecMax(int arr[],int nStart,int nEnd,int& nMax,int& nSecMax)
{
	assert(arr != NULL && nStart <= nEnd && nStart >= 0 && nEnd >= 0);
	int nLeftMax = 0;
	int nLeftSecMax = 0;
	int nRightMax = 0;
	int nRightSecMax = 0;
	if (nStart == nEnd - 1)//区间相差为1
	{
		if (arr[nStart] > arr[nEnd])
		{
			nMax = arr[nStart];
			nSecMax = arr[nEnd];
		}
		else
		{
			nMax = arr[nEnd];
			nSecMax = arr[nStart];
		}
		return;
	}
	if (nStart == nEnd)//区间相差为0
	{
		nSecMax = nMax = arr[nStart];
		return;
	}
	int nMid = (nStart + nEnd)/2;
	FindMaxAndSecMax(arr,nStart,nMid,nLeftMax,nLeftSecMax);
	FindMaxAndSecMax(arr,nMid + 1,nEnd,nRightMax,nRightSecMax);
	//分别比较两部分的最大值和次大值,求出整体的最大值和次大值
	if (nLeftMax > nRightMax)
	{
		nMax = nLeftMax;
		if (nLeftSecMax > nRightMax)
		{
			nSecMax = nLeftSecMax;
		}
		else
		{
			nSecMax = nRightMax;
		}
	}
	else
	{
		nMax = nRightMax;
		if (nRightSecMax > nLeftMax)
		{
			nSecMax = nRightSecMax;
		}
		else
		{
			nSecMax = nLeftMax;
		}
	}
}

int main()
{
	int nMin = 0;
	int nMax = 0;
	int arr[8] = {4,-3,5,-2,-1,2,6,-2};
	FindMaxAndSecMax(arr,0,7,nMax,nMin);
	cout<<"Max: "<<nMax<<endl;//6
	cout<<"Min: "<<nMin<<endl;//5

	int arr1[8] = {4,-3,5,-11,4,-2,5,-2};
	FindMaxAndSecMax(arr1,0,7,nMax,nMin);
	cout<<"Max: "<<nMax<<endl;//5
	cout<<"Min: "<<nMin<<endl;//5

	int arr2[8] = {-3,-5,-8,-2,-11,-12,-13,-1};
	FindMaxAndSecMax(arr2,0,7,nMax,nMin);
	cout<<"Max: "<<nMax<<endl;//-1
	cout<<"Min: "<<nMin<<endl;//-2
	system("pause");
	return 1;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值