zoukankan      html  css  js  c++  java
  • 152.乘积最大子序列

    思路:

      初版思路是将序列按照0拆开成若干子序列,然后在每个子序列里面判断负数的个数,若负数是偶数,直接相乘,若负数是奇数,要么从左往右相乘直到最后一个奇数,要么从右向左相乘知道第一个奇数

      修改版的思路是从左往右遍历+从右往左遍历,使用dp[i]保存相应方向直接相乘到i的数值。碰到0就跳过重新开始计算。

      最终版的思路是使用动态规划,记录以i点结束的最大值跟最小值,然后求max(dp_max * nums[i], dp_min * nums[i]) 与 num[i] 两者之间的最大值。常规dp。

    初版:

    runtime error

    class Solution {
    public:
        int maxProduct(vector<int>& nums) {
            int len = nums.size();
            if(len == 0)
                return 0;
            int odd_num = 0;
            int max_num = 1;
            for(int i = 0; i < len; i++)
            {
                if(nums[i] == 0)
                {
                    vector<int> vec1(nums.begin(), nums.begin() + i);
                    vector<int> vec2(nums.begin() + i+1, nums.end());
                    return max(maxProduct(vec1), maxProduct(vec2)) > 0 ? max(maxProduct(vec1), maxProduct(vec2)) : 0;
                }
                if(nums[i] < 0)
                    odd_num++;
            }
            if(len == 1)
            {
                return nums[0];
            }
            if(odd_num % 2 == 0)
            {
                for(auto i : nums)
                {
                    max_num *= i;
                }
                return max_num;
            }
            else
            {
                bool signal = true;
                int max1 = 1, max2 = 1;
                for(auto i : nums)
                {
                    if(!signal)
                        max1 *= i;
                    else if(i < 0)
                    {
                        signal = false;
                        continue;
                    }           }
                signal = true;
                for(int i = nums.size()-1; i >= 0; i--)
                {
                    if(!signal)
                        max2 *= nums[i];
                    else if(nums[i] < 0)
                    {
                        signal = false;
                        continue;
                    }
                    
                }
                return max(max1, max2);
            }
        }
    };

     修改版:

    执行用时 :8 ms, 在所有 C++ 提交中击败了77.55%的用户
    内存消耗 :9.1 MB, 在所有 C++ 提交中击败了44.38%的用户
    class Solution {
    public:
        int maxProduct(vector<int>& nums) {
            int len = nums.size();
            if(len == 0)
                return 0;
            vector<int> dp_l(len);
            vector<int> dp_r(len);
            for(int i = 0; i < len; i++)
            {
                dp_l[i] = nums[i];
                dp_r[i] = nums[i];
            }
            int max_l = dp_l[0];
            int max_r = dp_r[0];
            for(int i = 1; i < len; i++)
            {
                if(nums[i] == 0 || dp_l[i-1] == 0)
                    continue;
                dp_l[i] = dp_l[i-1] * nums[i];
                max_l = max(max_l, dp_l[i]);
            }
            for(auto i : dp_l)
            {
                max_l = max(i, max_l);
            }
            for(int i = len-2; i >= 0; i--)
            {
                if(nums[i] == 0 || dp_r[i+1] == 0)
                    continue;
                dp_r[i] = dp_r[i+1] * nums[i];
                max_r = max(max_r, dp_r[i]);
            }
            for(auto i : dp_r)
            {
                max_r = max(i, max_r);
            }
            return max(max_l, max_r);
        }
    };

     最终版:

    执行用时 :4 ms, 在所有 C++ 提交中击败了95.67%的用户
    内存消耗 :8.9 MB, 在所有 C++ 提交中击败了87.90%的用户
    class Solution {
    public:
        int maxProduct(vector<int>& nums) {
            int n = nums.size();
            int dp_min = nums[0], dp_max = nums[0];
            int maxVal = nums[0];
            
            for (int i = 1; i < n; ++i) {
                int _dp_min = dp_min * nums[i];
                int _dp_max = dp_max * nums[i];
                
                dp_min = min(nums[i], min(_dp_min, _dp_max));
                dp_max = max(nums[i], max(_dp_min, _dp_max));
                
                maxVal = max(maxVal, dp_max);
            }
            return maxVal;
        }
    };
  • 相关阅读:
    <meta>标签常用内容
    CentOS8 yum方式安装mysql8.0
    xshell上传下载文件
    CentOS8查看防火墙状态,开启/关闭防火墙
    CentOS8 yum方式安装nginx1.8
    Ant下载与配置
    List集合的方法总结
    List集合的三个实现类比较
    List集合遍历的三种方法
    JAVA如何跳出多层循环
  • 原文地址:https://www.cnblogs.com/CGJobs/p/11271961.html
Copyright © 2011-2022 走看看