假设我有一个这样的整数数组:
{ 3, 1, 6, 8, 2, 0, 1 }
我需要在每个元素左侧找到小于元素的最大元素,或者如果最大元素不存在则打印-1
。因此,解决这个问题的方法是:
{ -1, -1, 3, 6, 1, -1, 0 }
我可以使用两个循环在O(n^2)
中解决这个问题。内环将找到小于给定元素的最大元素。但有没有更好的方法来解决这个问题?
答案 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(" ");
}