给定一个数组,为每个元素找到数组中的下一个较小元素,而不改变元素的原始顺序.
例如,假设给定的数组是4,2,1,5,3.
结果数组为2,1,-1,3,-1.
我在接受采访时被问到这个问题,但我想不出一个比普通的O(n ^ 2)解决方案更好的解决方案.我能想到的任何方法,即制作二元搜索树,或对数组进行排序,都会扭曲元素的原始顺序,从而导致错误的结果.
任何帮助将受到高度赞赏.
Wee*_*ble 43
def find_next_smaller_elements(xs):
ys=[-1 for x in xs]
stack=[]
for i,x in enumerate(xs):
while len(stack)>0 and x<xs[stack[-1]]:
ys[stack.pop()]=x
stack.append(i)
return ys
>>> find_next_smaller_elements([4,2,1,5,3])
[2, 1, -1, 3, -1]
>>> find_next_smaller_elements([1,2,3,4,5])
[-1, -1, -1, -1, -1]
>>> find_next_smaller_elements([5,4,3,2,1])
[4, 3, 2, 1, -1]
>>> find_next_smaller_elements([1,3,5,4,2])
[-1, 2, 4, 2, -1]
>>> find_next_smaller_elements([6,4,2])
[4, 2, -1]
Run Code Online (Sandbox Code Playgroud)
这是有效的,因为无论何时我们将一个项添加到堆栈,我们都知道它的值已经大于或等于堆栈中的每个元素.当我们在数组中访问一个元素,我们知道,如果它是低于任何在堆栈中的项目,它必须比下最后堆栈中的项目,因为最后一个项目一定是最大的.所以我们不需要在堆栈上进行任何类型的搜索,我们可以考虑最后一项.
注意:只要添加最后一步以清空堆栈并使用每个剩余索引将相应的输出数组元素设置为-1,就可以跳过初始化步骤.在创建它时,Python更容易将其初始化为-1s.
这是O(N).主循环清楚地访问每个索引一次.每个索引都只添加到堆栈一次,最多删除一次.
这种问题在面试中可能会非常令人生畏,但我想指出(希望)面试官不会期望解决方案从你的脑海中完全形成.通过思考过程与他们交谈.我的事情是这样的:
即使你没有提出一个有效的算法,试着让你的面试官看到你在想什么.通常,思维过程不仅仅是他们感兴趣的答案.对于一个棘手的问题,未能找到最佳解决方案但是能够洞察问题可能比知道一个罐头答案更好但却无法给予它更多分析.