每日一练-----返回乘积最大的子数组的积
2016-05-05 10:42
288 查看
问题:
给定一个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;
之后只要求出上面三种情况的最大值,然后与临时变量的最大值取最大值即可;
代码:
如果想要计算出子数组乘积最大的这个子数组的话,定义一个长度为2的一维数组用来记录这个子数组的开始和结束位置,因为数组中可能会存在0元素,为了避免0元素,我们在遍历的过程中可能只会计算出正确的start或者end位置,为了标志到底是start正确还是end正确,我们使用了flag布尔型标志,最后根据flag来对相应的start以及end进行修正即可,修正策略是循环除以当前遍历到的元素,知道乘积为1结束即可;
代码:
给定一个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]+" "); } }
相关文章推荐
- jxl 和POI的区别
- VM10.0.1 build-1379776安装android-x86-4.4-r5.iso虚拟机 启动时error17的处理办法
- [No00008A]bat改变cmd命令提示符颜色
- React 官网列子学习
- JavaScript实现返回上一页面并刷新的小例子
- 在HDFS上配置Alluxio
- 《CSS3实战》笔记--渐变设计(二)
- (java)解决文件是中文名打包成zip文件名称乱码的问题。
- scala多值参数列表
- 使用Google开源tesseract OCR用语言库报allow_blob_division解决方案
- bzoj3585 mex 分块+莫队算法
- 用户空间的spi驱动
- form表单提交到servlet
- Linux后台开发应该具备技能
- App提交Appstore审核流程
- 步步学习python之环境安装:Vagrant+Ubuntu+Emacs+Virtualenv+Python3开发环境的搭建(Mac电脑下)4
- 最近改js学到的一些心得
- AFNetworking使用入门(随笔和链接)
- button添加到label上不能响应的问题解决
- 跳台阶问题