每日一练-----返回乘积最大的子数组的积

Posted 她说巷尾的樱花开了

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了每日一练-----返回乘积最大的子数组的积相关的知识,希望对你有一定的参考价值。

问题:

给定一个double类型的数组arr,其中元素可正可负,返回子数组累乘的最大乘积;

如:

arr  = [-2.5,4,0,3,0.5,8,-1]

则子数组[3,0.5,8]累乘获得最大乘积,返回12;

思想:

采用一个临时变量来存储遍历到当前位置的情况下所能够得到的最大乘积,这个值无非有三种可能性:

情况1:当前位置上的值是正数的话,那么有可能得到到达当前位置的时候的最大值是当前位置上的元素值乘以前面获得的最大值:如2,3,5到达5的时候,5>0,所以到达5之后的可能最大值是max*5,max是5之前获得的最大值;

情况2:当前位置上的值是负数的话,那么有可能得到到达当前位置的时候的最大值是当前位置上的元素值乘以前面获得的最小值:如-2,3,-5到达-5的时候,-5<0,所以到达-5之后的可能最大值是min*-5,min是-5之前获得的最小值;

情况3:就是当前位置上的值,如:0.1,0.1,50,那么到达当前位置50处的最大值可能是50;

之后只要求出上面三种情况的最大值,然后与临时变量的最大值取最大值即可;

代码:

public class MaxMulti 
	public static void main(String[] args) 
		double[] arr = -2.5,4,0,3,0.5,8,-1;
		System.out.println(getMaxMulti(arr));
	
	
	public static double getMaxMulti(double[] arr)
	
		double max = arr[0];
		double min = arr[0];
		double result = 0.0;
		for(int i = 1;i < arr.length;i++)
		
			max = max * arr[i];
			min = min * arr[i];
			max = Math.max(Math.max(max, min), arr[i]);
			min = Math.min(Math.min(max, min), arr[i]);
			result = Math.max(max, result);
		
		return result;
	

如果想要计算出子数组乘积最大的这个子数组的话,定义一个长度为2的一维数组用来记录这个子数组的开始和结束位置,因为数组中可能会存在0元素,为了避免0元素,我们在遍历的过程中可能只会计算出正确的start或者end位置,为了标志到底是start正确还是end正确,我们使用了flag布尔型标志,最后根据flag来对相应的start以及end进行修正即可,修正策略是循环除以当前遍历到的元素,知道乘积为1结束即可;

代码:

public class MaxMulti 
	public static void main(String[] args) 
		double[] arr = -2.5,4,0,3,0.5,0,8,-1;
		int[] result = getMaxMultiStartAndEnd(arr);
		print(arr, result[0], result[1]);
	
	
	public static int[] getMaxMultiStartAndEnd(double[] arr)
	
		int start = 0;
		int end = 0;
		int[] result = new int[2];
		boolean flag = true;//用flag来表示最后start的值是真正的start还是end是真正的end
		if(arr == null)
			return null;
		if(arr.length == 0)
		
			result[0] = 0;
			result[1] = 0;
			return result;
		
		double max = arr[0];
		double min = arr[0];
		double tempMax = arr[0];
		double tempMin = arr[0];
		double resultMax = arr[0];
		for(int i = 1;i < arr.length;i++)
		
			tempMax = max * arr[i];
			tempMin = min * arr[i];
			max = Math.max(Math.max(tempMax, tempMin), arr[i]);
			min = Math.min(Math.max(tempMax, tempMin), arr[i]);
			if(max > resultMax && max == arr[i])
			
				//设置开始位置为当前位置
				start = i;
				flag = true;
			else if(max > resultMax && max == Math.max(tempMax, tempMin))
			
				//设置结束位置向后移动
				end = i;
				flag = false;
			
		    resultMax = Math.max(max, resultMax);
		
		if(flag == false)
		
			//计算start的值(修正start的值)
			int i = end;
			while(resultMax != 1)
			
				resultMax = resultMax / arr[i];
				i--;
			
			result[0] = i+1;
			result[1] = end;
		else
		
			//计算end的值(修正end的值)
			int i = start;
			while(resultMax != 1)
			
				resultMax = resultMax / arr[i];
				i++;
			
			result[0] = start;
			result[1] = i-1;
		
		return result;
	
	
	public static void print(double[] arr,int start,int end)
	
		for(int i = start;i <= end;i++)
			System.out.print(arr[i]+" ");
	





以上是关于每日一练-----返回乘积最大的子数组的积的主要内容,如果未能解决你的问题,请参考以下文章

每日一练<4>

每日一练<4>

CSDN|每日一练连续子数组的最大和

CSDN|每日一练连续子数组的最大和

CSDN|每日一练查找整数

CSDN|每日一练查找整数