如何在元素左侧找到小于元素的最大元素?

时间:2014-09-14 15:40:34

标签: java c arrays algorithm max

假设我有一个这样的整数数组:

{ 3, 1, 6, 8, 2, 0, 1 }

我需要在每个元素左侧找到小于元素的最大元素,或者如果最大元素不存在则打印-1。因此,解决这个问题的方法是:

{ -1, -1, 3, 6, 1, -1, 0 }

我可以使用两个循环在O(n^2)中解决这个问题。内环将找到小于给定元素的最大元素。但有没有更好的方法来解决这个问题?

3 个答案:

答案 0 :(得分:3)

虽然这个问题与finding the rightmost element on the left hand side that is smaller无关,但是存在一个涉及堆栈的可爱线性时间算法的问题,它是密切相关的。要解决此问题,请按值对数组索引和值进行排序,然后从链接问题运行算法,将索引视为值。这避免了二叉搜索树强加的常数因素。

由于排序不同的元素是线性时间可以减少到这个问题,O(sort(n))的运行时间或多或少是最优的。

Python实现(比预期更精细;请注意sorted不能重新排列比较相等的元素。

def alg(lst):
    indexes = sorted(range(len(lst) - 1, -1, -1), key=lst.__getitem__)
    stack = []
    out = [-1] * len(lst)
    for i in indexes:
        while stack and i < stack[-1]:
            del stack[-1]
        if stack:
            out[i] = lst[stack[-1]]
        stack.append(i)
    return out


print(alg([3, 1, 6, 8, 2, 0, 1]))

答案 1 :(得分:2)

您可以将目前为止找到的数字存储在树形图中。将其索引与数字一起存储。当您到达索引i处的数字时,请在树中查找低于array[i]的最高数字。使用lowerEntry可以在Log 2 N时间内进行,使整体时间N * Log 2 N

答案 2 :(得分:0)

步骤:

1:对于第一个元素,我们可以在答案后面加上-1。

2:将i循环遍历列表中的第一个元素,并继续向树集添加第(i-1)个元素。

3:要找到greatSmaller元素,我们可以通过     set.lower(Element)

4:如果结果为null,则只需附加-1。

这是一个实现

    StringBuilder b = new StringBuilder();
    TreeSet<Integer> set = new TreeSet<>();
    b.append(-1);
    b.append(" ");
    for(int i = 1; i<a.length; i++){
        set.add(a[i-1]);
        Integer result = set.lower(a[i]);
        if(result != null)
            b.append(result);
        else
            b.append(-1);
        b.append(" ");
    }