使用分而治之的最大子阵列产品有人吗?

Posted

技术标签:

【中文标题】使用分而治之的最大子阵列产品有人吗?【英文标题】:Maximum subArray product using Divide and Conquer Anyone? 【发布时间】:2021-03-20 09:31:40 【问题描述】:

我知道这是涉及整数数组时最常见的编码问题之一。我正在寻找一种解决方案来解决在数组中找到最长的连续 subArray 产品的问题,但使用的是分而治之的方法。

我将输入数组分成两半:递归求解左右数组,以防解决方案完全落在半数组中。我遇到的问题是 subArray 穿过数组中点的场景。这是我处理交叉点的函数的简短 sn-p 代码:

pair<int,pair<int, int>> maxMidCrossing(vector<int>& nums, int low, int mid, int high)
    
        int m = 1;
        int leftIndx = low;
        long long leftProduct = INT_MIN;

        for(int i = mid-1; i>= low; --i)
        
            m *= nums[i];
            if(m > leftProduct) 
                leftProduct = m;
                leftIndx = i;
            
        
        
        int mleft = m;
        m=1;
        int rightIndx = high;
        long long rightProduct = INT_MIN;
        
        for(int i = mid; i<= high; ++i) 
        
             m *= nums[i];
            if(m > rightProduct) 
                rightProduct = m;
                rightIndx = i;
            
        
        
        int mright = m;
        cout << "\nRight product " << rightProduct;
        pair<int, int> tmp;
        int maximum = 0;
        
        // Check the multiplication of both sides of the array to see if the combined subarray satisfies the maximum product condition. 

        if(mleft*mright < leftProduct*rightProduct) 
            tmp = pair(leftIndx, rightIndx);
            maximum = leftProduct*rightProduct;
        
        
        else 
            tmp = pair(low, high);
            maximum = mleft*mright;
        

        return pair(maximum, tmp);
    

处理整个搜索的函数包含以下内容:

auto leftIndx = indexProduct(left);
    auto rightIndx = indexProduct(right);
    auto midResult = maxMidCrossing(nums, 0, mid, nums.size()-1); // middle crossing

//.....更多代码............

if(mLeft > midProduct && mLeft > mRight)
            tmp=leftIndx;
        
        else if (mRight > midProduct && mRight > mLeft)
             tmp = pair(rightIndx.first + mid, rightIndx.second + mid);
        
        else tmp=midIndx;

最后,我只计算了 3 个场景的最大乘积:左数组、交叉数组、右数组。

我仍然有一些极端案例失败了。我的问题是这个问题是否承认分而治之类型的递归解决方案,如果有人能发现我在代码中可能做错了什么,我将不胜感激任何可以帮助我摆脱困境的提示。

谢谢, 胺

【问题讨论】:

【参考方案1】:

从 leetcode 看看这些

C++ 分而治之

https://leetcode.com/problems/maximum-product-subarray/discuss/48289/c++-divide-and-conquer-solution-8ms

Java https://leetcode.com/problems/maximum-product-subarray/discuss/367839/java-divide-and-conquer-2ms

c# https://leetcode.com/problems/maximum-product-subarray/discuss/367839/java-divide-and-conquer-2ms

【讨论】:

我的解决方案看起来几乎与您提供的解决方案相似,只是我缺少 lmin*rmin 比较,这在这里很重要,因为我们使用乘法时符号翻转,与 sum 的符号相反两个子项都没有任何影响。

以上是关于使用分而治之的最大子阵列产品有人吗?的主要内容,如果未能解决你的问题,请参考以下文章

使用分而治之的最大子数组

最大和子数组 - 返回子数组和总和 - 分而治之

如何使用分而治之的方法解决“固定大小的最大子数组”?

用于查找最大子数组的分而治之算法 - 如何同时提供结果子数组索引?

最大子数组:分而治之

使用分而治之的最大连续和