数组平衡点

时间:2011-03-22 21:50:22

标签: c++

解决此问题的最佳方法是什么? N元素阵列A的平衡点是索引i,使得较低索引上的所有元素具有值<= A [i]并且较高索引上的所有元素具有高于或等于A [i]的值。

例如,给定:

A [0] = 4 A [1] = 2 A [2] = 7 A [3] = 11 A [4] = 9

正确的解决方案之一是:2。A [2]以下的所有元素都小于A [2],A [2]之后的所有元素都大于A [2]。 在我看来,一个解决方案是O(nsquare)解决方案。有没有更好的解决方案?

5 个答案:

答案 0 :(得分:5)

首先假设A[0]是极点。然后开始走阵列;将每个元素A[i]依次与A[0]进行比较,并跟踪当前的最大值。

一旦找到i A[i] < A[0] A[0],就会知道A[i]不再是一个极点,并且通过扩展,任何元素都不能和包括int i_pole = 0; int i_max = 0; bool have_pole = true; for (int i = 1; i < N; i++) { if (A[i] < A[i_pole]) { have_pole = false; } if (A[i] > A[i_max]) { i_max = i; if (!have_pole) { i_pole = i; } have_pole = true; } } 。所以现在继续走,直到找到比当前最大值更大的下一个值。这就成了新提出的极点。

因此, O(n)解决方案!

在代码中:

{{1}}

答案 1 :(得分:3)

如果你想知道所有极点在哪里, O(n log n)解决方案就是创建一个数组的排序副本,并查看你得到匹配值的位置。

编辑:对不起,但这实际上并不奏效。一个反例是[2, 5, 3, 1, 4]

答案 2 :(得分:1)

创建两个辅助数组,每个数组包含与输入数组一样多的元素,称为MIN和MAX。 MAX的每个元素M包含0..M输入中所有元素的最大值。 MIN的每个元素M包含M..N-1输入中所有元素的最小值。

对于输入数组的每个元素M,将其值与MIN和MAX中的相应值进行比较。如果INPUT [M] == MIN [M]和INPUT [M] == MAX [M]则M是一个平衡点。

构建MIN需要N步,MAX也是如此。然后测试阵列需要N个步骤。该解决方案具有O(N)复杂度并且找到所有平衡点。在排序输入的情况下,每个元素都是一个平衡点。

答案 3 :(得分:0)

创建一个双链表,例如此列表的第i个节点包含A[i]i。元素增长时遍历此列表(计算这些元素的最大值)。如果某些A[bad] < maxSoFar它不能成为MP。删除它并向后移除元素,直到找到A[good] < A[bad]或到达列表的头部。继续(以maxSoFar作为最大值开始),直到您到达列表的末尾。结果列表中的每个元素都是MP,每个MP都在此列表中。复杂性是 O(n),因为对于降序数组执行最多步骤 - n前进和n删除。

更新

哦,我在问题定义中把“任何”与“每个”混淆了:)。

答案 4 :(得分:0)

你可以结合bmcnett和Oli的答案,尽快找到所有的极点。

std::vector<int> i_poles;
i_poles.push_back(0);
int i_max = 0;
for (int i = 1; i < N; i++)
{
    while (!i_poles.empty() && A[i] < A[i_poles.back()])
    {
        i_poles.pop_back();
    }
    if (A[i] >= A[i_max])
    {
        i_poles.push_back(i);
    }
}

如果您想避免重新分配,可以使用预先分配为N的数组。