Algorithm 两个直方图之间收集的最大水量是多少?

Algorithm 两个直方图之间收集的最大水量是多少?,algorithm,Algorithm,我最近遇到了这个问题: 您将看到宽度为1的高度为n直方图。您必须选择任意两个柱状图,以便在开始下雨时,删除所有其他柱状图(您选择的两个柱状图除外),然后将两个柱状图之间收集的水最大化 输入: 9 3 2 5 9 7 8 1 4 6 输出: 25 在第三个和最后一个柱状图之间 这是问题的变体 我尝试了两种解决方案,但都有N^2的最坏情况复杂性。我们如何进一步优化 解决方案1:每对都使用蛮力 int maxWaterCollected(vector<int> hist, int n)

我最近遇到了这个问题:

您将看到宽度为1的高度为
n
直方图。您必须选择任意两个柱状图,以便在开始下雨时,删除所有其他柱状图(您选择的两个柱状图除外),然后将两个柱状图之间收集的水最大化

输入:
9
3 2 5 9 7 8 1 4 6
输出:
25
在第三个和最后一个柱状图之间

这是问题的变体

我尝试了两种解决方案,但都有N^2的最坏情况复杂性。我们如何进一步优化

  • 解决方案1:每对都使用蛮力

    int maxWaterCollected(vector<int> hist, int n) {
        int ans = 0;
        for (int i= 0; i < n; i++) {
            for (int j = i + 1; j < n; j++) {
                ans = max(ans, min(hist[i], hist[j]) * (j - i - 1));
            }
        }
    
        return ans;
    }
    
    int-maxWaterCollected(向量历史,int-n){
    int ans=0;
    对于(int i=0;i
  • Sol2:按高度的递增顺序保留直方图序列。对于每个直方图,在此序列中找到其最佳直方图。现在,如果所有直方图都是递增的,那么这个解也变成了N^2

    int maxWaterCollected(vector<int> hist, int n) {
        vector< pair<int, int> > increasingSeq(1, make_pair(hist[0], 0)); // initialised with 1st element.
        int ans = 0;
        for (int i = 1; i < n; i++) {
            // compute best result from current increasing sequence
            for (int j = 0; j < increasingSeq.size(); j++) {
                ans = max(ans, min(hist[i], increasingSeq[j].first) * (i - increasingSeq[j].second - 1));
            }
    
            // add this histogram to sequence
            if (hist[i] > increasingSeq.back().first) {
                increasingSeq.push_back(make_pair(hist[i], i));
            }
        }
    
        return ans;
    }
    
    int-maxWaterCollected(向量历史,int-n){
    向量increasingSeq(1,make_pair(hist[0],0));//用第一个元素初始化。
    int ans=0;
    对于(int i=1;iincreasingSeq.back().first){
    增加seq.push_back(生成一对(hist[i],i));
    }
    }
    返回ans;
    }
    

使用两个迭代器,一个来自
begin()
,另一个来自
end()-1

  • 直到2个迭代器相等:
  • 将当前结果与最大值进行比较,并保持最大值
  • 使用较小的值移动迭代器(开始->结束或结束->开始)
复杂性:
O(n)

的想法是正确的,但从他简洁的帖子中不清楚为什么下面用Python描述的算法是正确的:

def candidates(hist):
    l = 0
    r = len(hist) - 1
    while l < r:
        yield (r - l - 1) * min(hist[l], hist[r])
        if hist[l] <= hist[r]:
            l += 1
        else:
            r -= 1


def maxwater(hist):
    return max(candidates(hist))
def候选者(历史):
l=0
r=len(hist)-1
而l如果hist[l]我已经提到了我的两种方法,第一种是暴力,另一种是不断增加直方图的子序列,但我认为这个问题可以在更高的时间复杂度下解决。[c++]观众倾向于对这些问题投反对票,因为“缺乏努力”。我在这里没有看到任何努力。“我尝试了两种解决方案”,但没有发布任何代码?如果您确实尝试过,请添加您所做的代码。