我尝试解决以下问题。给定每个元素的实数[7, 2, 4, 8, 1, 1, 6, 7, 4, 3, 1]
数组,我需要找到数组中最近的前一个更大的元素。
例如,没有什么比第一个元素(7)更大,所以它有NaN。对于第二个元素(2),7更大。所以最后答案如下:
[NaN, 7, 7, NaN, 8, 8, 8, 8, 7, 4, 3, 1]
。当然,我可以检查每个元素的所有前面的元素,但这在数组的元素数量方面是二次的。
我的另一种方法是维护先前元素的排序列表,然后选择大于当前的第一个元素。这听起来像是一个线性的日志(我不确定)。有没有更好的方法来解决这个问题?
答案 0 :(得分:3)
这是一种方法
create a stack which is initially empty
for each number N in the array
{
while the stack is not empty
{
if the top item on the stack T is greater than N
{
output T (leaving it on the stack)
break
}
else
{
pop T off of the stack
}
}
if the stack is empty
{
output NAN
}
push N onto the stack
}
获取样本数组[7,2,4,8,1,1,6,7,4,3,1],这里有算法如何解决它。
stack N output
- 7 NAN
7 2 7
7 2 4 7
7 4 8 NAN
8 1 8
8 1 1 8
8 1 6 8
8 6 7 8
8 7 4 7
8 7 4 3 4
8 7 4 3 1 3
理论上说,堆栈不需要保留小数,因为它们永远不会成为输出的一部分。例如,在序列7, 2, 4
中,不需要2,因为任何小于2的数字也将小于4.因此堆栈只需要保留7和4。
复杂性分析
算法的时间复杂度可以显示为 O(n),如下所示:
n
次推送(输入数组中的每个数字都是
被推入堆栈一次,只有一次)n
个弹出窗口(一旦从堆栈中弹出一个数字,
它被丢弃了)n
次比较失败(因为数字已弹出
并且在比较失败后丢弃)n
次成功比较(自算法以来)
成功后移动到输入数组中的下一个数字
比较)n
个输出操作(自算法以来)
为输入数组中的每个数字生成一个输出)因此我们得出结论,该算法在大多数5n
操作中执行以完成任务,这是 O(n)的时间复杂度。
答案 1 :(得分:2)
我们可以为每个数组元素保留其最新的更大元素的索引。当我们处理一个新元素x时,我们检查前一个元素y。如果y更大,那么我们找到了我们想要的东西。如果没有,我们检查哪个是y的最新更大元素的索引。我们继续,直到找到我们需要的元素及其索引。使用python:
a = [7, 2, 4, 8, 1, 1, 6, 7, 4, 3, 1]
idx, result = [], []
for i, v in enumerate(a, -1):
while i >= 0 and v >= a[i]:
i = idx[i]
idx.append(i)
result.append(a[i] if i >= 0 else None)
结果:
[None, 7, 7, None, 8, 8, 8, 8, 7, 4, 3]
算法是线性的。由于我们正在查找索引j
中最新的较大元素,因此检查索引i > j
未成功,从现在起i
将指向比j
更小的索引, j
将不再被检查。
答案 2 :(得分:0)
为什么不定义变量'current_largest'并从左到右遍历数组?在每个元素处,当前最大值是最大值,如果当前元素较大,则将current_largest分配给当前元素。然后转到下一个元素。
编辑: 我只是重新阅读你的问题,我可能误解了它。你想找到以前更大的元素吗?
EDIT2: 在我看来,目前最大的方法将起作用。您只需要在为其指定新值之前记录current_largest。例如,在python中:
current_largest = 0
for current_element in elements:
print("Largest previous is "+current_largest)
if(current_element>current_largest):
current_largest = current_element
如果你想要这些数组,那么只需将值推送到数组代替print语句。
答案 3 :(得分:0)
根据我对你的问题的最佳理解。以下是一个解决方案。 工作示例:JSFIDDLE
var item = document.getElementById("myButton");
item.addEventListener("click", myFunction);
function myFunction() {
var myItems = [7, 2, 4, 8, 1, 1, 6, 7, 4, 3, 1];
var previousItem;
var currentItem;
var currentLargest;
for (var i = 0; i < myItems.length; i++) {
currentItem = myItems[i];
if (i == 0) {
previousItem = myItems[0];
currentItem = myItems[0];
myItems[i] = NaN;
}
else {
if (currentItem < previousItem) {
myItems[i] = previousItem;
currentLargest = previousItem;
}
if (currentItem > currentLargest) {
currentLargest = currentItem;
myItems[i] = NaN;
}
else {
myItems[i] = currentLargest;
}
previousItem = currentItem;
}
}
var stringItems = myItems.join(",");
document.getElementById("arrayAnswer").innerHTML = stringItems;
}