题解 | #子数组最大乘积#
子数组最大乘积
http://www.nowcoder.com/practice/9c158345c867466293fc413cff570356
随手记录下解题过程,各位看官将就看下吧--------
这个题目其实是要求【连续】子数组,一开始理解错了,一直没通过
实际代码没有用dp数组,采用【滚动数组】思想(可以参考leetcode152),用两个变量保存最大和最小值,因为当前最值只和上一个最值有关
// NC83子数组最大乘积 /* 状态定义: dp_max[i]:以下标为i的【连续】子数组的最大乘积 dp_min[i]:以下标为i的【连续】子数组的最小乘积 状态转移: arr[i]>0时,希望上一次的乘积尽可能大,正*正=正,乘积才能尽可能大; arr[i]<=0时,希望上一次的乘积尽可能小,负*负=正,乘积才能尽可能大; 方程式: dp_max[i]=max(arr[i],dp_max[i-1]*arr[i]);//(arr[i]>0) dp_min[i]=min(arr[i],dp_min[i-1]*arr[i]);//(arr[i]>0) dp_max[i]=max(arr[i],dp_min[i-1]*arr[i]);//(arr[i]<=0) dp_min[i]=min(arr[i],dp_max[i-1]*arr[i]);//(arr[i]<=0) 返回结果: 每次子数组长度+1,就判断当前长度下最大的乘积。最后返回最大的即可。 */ class Solution { public: double maxProduct(vector<double> arr) { int len=arr.size(); vector<int>dp(len); if(len==0) return 0; if(len==1) return arr[0]; // 初始化 double max_num=arr[0];//最大乘积 double min_num=arr[0];//最小乘积 double ret=max_num;//返回值,注意是double类型 // 循环 // dp[0]=arr[0]; for(int i=1;i<len;++i){ if(arr[i]>0){ max_num=max( arr[i],arr[i]*max_num); min_num=min( arr[i],arr[i]*min_num); }else{ double tmp_max=max_num; double tmp_min=min_num; max_num=max(arr[i],arr[i]*tmp_min); //此处求min的时候不能直接使用max_num,该max_num是最新的,而不是上次的 // min_num=min(arr[i],arr[i]*max_num); 错误!! min_num=min(arr[i],arr[i]*tmp_max);//正确 } ret=max(ret,max_num); } return ret; } };