给出k个块的系列(k1,k2,...,ki)。每个块从位置ai开始并在位置bi结束并且其高度为1.块连续放置。如果该块与另一个块重叠,则它被连接在其顶部。我的任务是计算最高的积木塔。 我已经创建了一个时间复杂度约为O(n ^ 2)的算法,但我知道使用skiplist有一个更快的解决方案。
#include <iostream>
struct Brick
{
int begin;
int end;
int height = 1;
};
bool DoOverlap(Brick a, Brick b)
{
return (a.end > b.begin && a.begin < b.end)
}
int theHighest(Brick bricks[], int n)
{
int height = 1;
for (size_t i = 1; i < n; i++)
{
for (size_t j = 0; j < i; j++)
{
if (bricks[i].height <= bricks[j].height && DoOverlap(bricks[i], bricks[j]))
{
bricks[i].height = bricks[j].height + 1;
if (bricks[i].height > height)
height = bricks[i].height;
}
}
}
return height;
}
答案 0 :(得分:1)
You can simply use 2 pointers after sorting the blocks based on their starting positions, if their starting positions match sort them based on their ending positions. Then simply use the 2 pointers to find the maximum height.
Time complexity : O(NlogN)
You can find the demo link here
.modalBox.modalBox
答案 1 :(得分:0)
这是一个简单的解决方案(没有跳过列表):
创建数组heights
遍历块。
对于每个块
通过迭代当前块占据的位置,检查高度数组中的现有条目。确定它们的最大值。
将当前块的高度数组中的值增加到上一步中确定的最大值+ 1.
保持扫描过程中建立的最大塔的分数。
答案 2 :(得分:0)
This problem is isomorphic to a graph traversal. Each interval (block) is a node of the graph. Two blocks are connected by an edge iff their intervals overlap (a stacking possibility). The example you give has graph edges
-47.121314
Your highest stack is isomorphic to the longest cycle-free path in the graph. This problem has well-known solutions.
BTW, I don't think your n^2 algorithm works for all orderings of blocks. Try a set of six blocks with one overlap each, such as the intervals [n, n+3] for n in {2, 4, 6, 8, 10, 12}. Feed all permutations of these blocks to your algorithm, and see whether it comes up with a height of 6 for each.
Complexity
I think the highest complexity is likely to be sorting the intervals to accelerate marking the edges. The sort will be O(n log n). Adding edges is O(n d) where d is the mean degree of the graph (and n*d is the number of edges).
I don't have the graph traversal algorithm solidly in mind, but I expect that it's O(d log n).
答案 3 :(得分:0)
看起来您可以将已处理的块存储在跳过列表中。块应按起始位置排序。然后,要在每个步骤中找到重叠块,您应该在此跳过列表中搜索平均为O(log n)。您找到第一个重叠块然后迭代到下一个,依此类推,直到您遇到第一个非重叠块。
所以平均来说你可以得到O(n *(log(n)+ m))其中m - 是重叠块的平均数。在最坏的情况下,你仍然得到O(n ^ 2)。