查找JavaScript数组中最后一个元素的计算效率最高的方法是什么?

查找JavaScript数组中最后一个元素的计算效率最高的方法是什么?,javascript,arrays,Javascript,Arrays,使用起来会更快吗 var lastelement = myarray[myarray.length - 1]; 或 为什么呢?想想看 如果您知道数组的长度,那么只获取最后一个值要比计算相反的值快得多 通过索引访问元素更快,因为它应该具有O(1)复杂度。另一方面,反转数组然后访问第一个索引的复杂性至少为O(n),这取决于反转算法的实现方式。我将从一个不同的角度来理解这一点。很可能您只想得到最后一个元素,而不想对实际数组本身做任何事情。如果您使用array.reverse来获取最后一个元素,那么实

使用起来会更快吗

var lastelement = myarray[myarray.length - 1];

为什么呢?

想想看


如果您知道数组的长度,那么只获取最后一个值要比计算相反的值快得多

通过索引访问元素更快,因为它应该具有O(1)复杂度。另一方面,反转数组然后访问第一个索引的复杂性至少为O(n),这取决于反转算法的实现方式。

我将从一个不同的角度来理解这一点。很可能您只想得到最后一个元素,而不想对实际数组本身做任何事情。如果您使用
array.reverse
来获取最后一个元素,那么实际上您正在更改数组(在您的情况下,这可能是一个令人不快的副作用)

因此,如果要在不更改数组的情况下获取最后一个元素,则必须执行以下操作:

var myArray = [.....]; // some array
var lastElement = myArray.slice().reverse()[0]; // copy and get the last element
var firstElement = myArray[0]; // this is the correct first element

很明显,现在哪种方法更有效。

真正有效的解决方案是使用红色和黑色二叉树(),在其中,您将在每个节点中存储一个数组值、上一个和下一个项目的增量以及与中值的相对位置。然后,只需进行几次遍历,您就应该能够识别最后一个元素(最后一个元素的索引与中值索引的差值最大,而上一个项目没有下一个项目)

诀窍是每次遍历只需要O(ln(n)),因为您的遍历次数少于ln(n),所以时间低于O(sq(ln(n)),所以速度非常快

编辑:按照Bergi的建设性意见,我只是想知道,仅仅使用数组是否会更快,通过对包含数组所有索引的数组使用快速傅立叶变换,然后通过频率分析识别最后一个元素,然后将数组转换回频率以外的数。如果我不清楚,我很抱歉,我在写这篇文章时没有清楚地看到所有步骤,但我认为这是一个值得遵循的想法。

Array.reverse()在同一引用中用新的反向数组替换旧数组,用新元素封装新数组要比按索引获取数组元素慢得多。 var lastelement=myarray[myarray.length-1];
要快得多。

反转数组只是为了得到最后一个元素?认真地顺便说一句,您可能忘记了一些括号。请注意,您可以自己测试,而不是这样问,例如使用micro optimization alert!我想你的意思是
myarray.reverse()[0]
。也许它能更好地向你展示计算的不同之处。从牌组底部取下一张牌,或者颠倒整个牌组的顺序,然后从顶部取下一张牌,哪个更快?复杂性不是速度。当然,查询长度更快,但这不是证据。编辑:嗯,事实上,他要求的是最快的方法。我很抱歉。我可以问你为什么复杂性并不意味着速度吗?@luizrogeriocn:对于小输入,有时复杂度更差的简单解决方案比更高效的算法更快,有时它们仍然适用于惊人的大输入。我们可以假设数组(和向量)具有已知的长度和恒定的查找时间,因此,这比大多数树实现要好得多:-)@Bergi:谢谢,我必须深入研究javascript规范。我编辑了。嗯,看来你误解了这个问题。OP只想访问数组中的“最后一个”元素,而不是确定最大的元素或其他什么。为什么用反向myArray定义lastElement会改变myArray本身的定义?这就像说VarFoo=2,然后说VarBar=foo+1,现在期望foo==3。我遗漏了什么吗?
reverse()
方法更改了数组对象本身,而不是简单地返回一个新的、反转的数组(它返回相同的、变异的数组),这可能会导致意外的结果。然而,你的误解可能是由于我的回答的措辞造成的。使用您的示例,就像说,
var foo=2,bar=foo++现在
bar==3
foo==3
哦,很有趣。我没有意识到这样的方法会改变内存中的原始变量。我认为它们只影响新定义中使用的借用引用。记住这一点很好。谢谢请格式化您的代码以提高答案的可读性。
var myArray = [.....]; // some array
var lastElement = myArray.reverse()[0]; // get the last element
var firstElement = myArray[0]; // tricked you! This is now the same as
                               // lastElement because the myArray object
                               // in memory has been reversed.
var myArray = [.....]; // some array
var lastElement = myArray.slice().reverse()[0]; // copy and get the last element
var firstElement = myArray[0]; // this is the correct first element