第二十八章续:任意(N-1)个数的组合中乘积最大的一组

本文介绍了一种寻找整数数组中(N-1)个数的最大乘积组合的算法,提供了两种实现方法并分析了时间复杂度。方法一利用辅助数组记录部分乘积,方法二通过统计正负数数量及特殊值来优化计算。

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

题目描述:

给定一个长度为N的整数数组,只允许用乘法,不能用除法,计算任意(N-1)个数的组合中乘积最大的一组,并写出算法的时间复杂度。


#include <iostream>     
#include <algorithm>
#include <functional>
using namespace std;    

/*
给定一个长度为N的整数数组,只允许用乘法,不能用除法,
计算任意(N-1)个数的组合中乘积最大的一组,并写出算法的时间复杂度。
*/
/*方法1:
s[i]表示0到i-1乘积,t[i]表示i+1到n乘积,有Max={s[i]*t[i]}
*/
long caculate(int arr[],int length){
	long maxV=LONG_MIN;
	long *s=new long[length+1];
	long *t=new long[length+1];
	s[0]=1,t[length-1]=1;
	for(int i=1;i<=length;++i)
		s[i]=s[i-1]*arr[i-1];
	for(int i=length-2;i>=0;--i){
		t[i]=t[i+1]*arr[i+1];
	}
	for(int i=0;i<length;++i)maxV=max(maxV,s[i]*t[i]);
	delete[] s;
	delete[] t;
	return maxV;
}
/*方法2:
统计数组中正负零的个数
*/
long caculate2(int arr[],int length){
	long multi=1;//结果
	bool flag=false;//标识,数组中去掉的只能是一个数
	int opt=0,neg=0,zero=0;//正负零的个数
	int minO=INT_MAX,maxN=INT_MIN;//最小的正数和最大的负数
	for(int i=0;i<length;i++){
		if(arr[i]<0){neg++;maxN=max(maxN,arr[i]);}
		else if(arr[i]>0){opt++;minO=min(minO,arr[i]);}
		else zero++;
	}
	if(zero>1)return 0;
	//1个0的情况
	if(zero==1){
		if(neg&1)return 0;//奇数个负数
		else{
			for(int i=0;i<length;++i)
				if(arr[i]!=0)multi*=arr[i];
			return multi;
		}
	}
	//有奇数个负数,去掉最大的负数,即绝对值最小的负数
	if(neg&1){
		for(int i=0;i<length;++i){
			if(arr[i]!=maxN||flag){
				multi*=arr[i];
			}
			else flag=true;
		}
		return multi;
	}
	//有偶数个负数,去掉最小的正数
	for(int i=0;i<length;++i){
		if(arr[i]!=minO||flag){
			multi*=arr[i];
		}
		else flag=true;
	}
	return multi;
}
int main()    
{    
	int arr[]={-2,0,-3,-4,5,6,-1,-3};
	cout<<caculate2(arr,8);
}    


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值