我最近遇到了一个有趣的编码问题,如下:
有n个框,我们假设这是一个n个框的数组。
对于此数组的每个索引i,给出了三个值 -
1。)体重(i)
2。)左(i)
3。)对(i)
left(i)
表示 - 如果选择weight[i]
,我们将不允许从此left[i]
左侧选择ith element
个元素。
同样,right[i]
表示如果选择arr[i]
,我们就不允许从右侧选择right[i]
元素。
示例:
体重[2] = 5
左[2] = 1
右[2] = 3
然后,如果我在第2位选择元素,我得到5个单位的重量。但是,我无法在位置{1}处选择元素(由于左边约束)。并且不能在{3,4,5}位置挑选元素(由于正确的约束)。
目标 - 我们需要计算我们可以选择的权重的最大总和。
示例测试用例: -
**输入:**
5
2 0 3
4 0 0
3 2 0
7 2 1
9 2 0
**输出:**
13
注意 - 第一列是权重,第二列是左约束,第三列是右约束
我使用动态编程方法(类似于最长增加子序列)来达到O(n^2)
解决方案。但是,无法想到O(n*logn)
解决方案。 (n can be up to 10^5.)
我还尝试使用优先级队列,其中(right[i] + i)
值较低的元素被赋予较高的优先级(为具有较低值&#34的元素分配较高优先级; i&# 34;,如果主键值相等)。但是,它也给出了超时错误。
还有其他方法吗?或优先队列方法的任何优化?如果需要,我可以发布我的两个代码。 感谢。
答案 0 :(得分:0)
一种方法是使用binary indexed tree创建一个数据结构,以便在O(logn)时间内轻松完成两个操作:
我们将使用此数据结构来保持可以通过选择方框i以及左侧最佳选择框来实现的最大权重。
关键是当我们到达满足正确约束的点时,我们只会将值插入到此数据结构中。
为了找到方框i的最佳值,我们需要找到数据结构中所有点的最大值,直到位置i-left [i],这可以在O(logn)中完成。
最终的算法是遍历i = 0..n-1和每个i:
最终结果是整个数据结构中的最大值。
总体而言,复杂度为o(nlogn),因为i的每个值都会导致一次查找和一次更新操作。