让我们设置上下文/限制:
下面是我建议的解决方案的一些代码。
Node cursor = head;
Node middle = head;
while (cursor != null) {
cursor = cursor.next;
if (cursor != null) {
cursor = cursor.next;
middle = middle.next;
}
}
return middle;
在不改变链表结构(不切换到双链表或存储长度变量)的情况下,有没有更有效的方法来查找单链表的中间元素?
注意:当此方法找到偶数个节点的中间时,它总是找到左中间。这是理想的,因为它允许您访问两者,但是如果一个更有效的方法总是能找到正确的中间,那也没关系。
不,考虑到你所掌握的信息,没有比这更有效的方法了。
考虑从一个节点到下一个节点的转换。您必须执行N
转换来计算列表长度。然后必须执行N/2
转换以找到中间位置。
无论您是根据查找到的长度先进行全扫描,然后进行半扫描,还是并行运行光标
(速度为两倍)和中间
(速度为正常)指针,都与此无关,转换的总数保持不变。
使其更快的唯一方法是向您已经忽略的数据结构引入额外的信息,但是,为了完整起见,我将在这里包含它。例如:
>
使其成为具有head
和尾部
指针的双链表,因此您可以通过从两端向中间挤压在N
转换中找到它。这将指针的存储需求增加了一倍,但是可能不合适。
有一个跳过列表,每个节点都指向它的“子”和“孙子”。这将加速cursor
转换,导致总共只有大约N
(即每个cursor
和中间
的N/2
)。像前一点一样,每个节点需要一个额外的指针。
单独维护列表的长度,以便您可以在N/2
转换中找到中间。
与上一点相同,但在某些情况下缓存中间节点以提高速度。
最后一点需要额外检查。像许多优化一样,您可以用空间换取时间,缓存显示了一种方法。
首先,保持列表的长度和指向中间节点的指针。长度最初为零,中间指针最初设置为null
。
如果在长度为零时要求使用中间节点,只需返回null
。这是有道理的,因为列表是空的。
否则,如果您被要求输入中间节点,而指针为null
,那一定是因为您还没有缓存该值。
在这种情况下,使用长度(N/2
transitions)计算该指针,然后在返回该指针之前存储该指针以备将来使用。
顺便说一句,当添加到列表末尾时,这里有一个特殊的情况,一些足够常见的情况需要特殊的代码。
当长度从偶数增加到奇数时,只需将middle
设置为middle即可-
这将保存重新计算并起作用,因为您(a)有
下一个
指针,并且(b)您可以计算出中间“索引”(基于一个索引,并根据原始问题选择一对索引的左边)在给定长度时的变化:
Length Middle(one-based)
------ -----------------
0 none
1 1
2 1
3 2
4 2
5 3
: :
这种缓存意味着,如果列表不发生变化(或者只在末尾发生变化),下次您需要中间元素时,它几乎是即时的。
如果从列表中删除节点(或插入endpoint以外的其他位置),请将中间指针设置回null。然后在下次需要时重新计算(并重新缓存)。
因此,对于最小的额外存储需求,您可以获得相当大的速度,特别是在需要中间元素的情况下,而不是在更改列表的情况下。
我正在开发一个java程序,它接受输入的分数,给出输入的总数和平均值,但是我很难计算出如何获得当前输入的最高分数“我使用了大量嵌套的else-if语句,但必须有一种简单的方法来实现这一点,而不是键入100个else-if语句这是我的代码。我在else-if语句开始的地方添加了一条注释,以确定最高级别
问题内容: 有没有一种方法可以序列化angularjs的功能? 我的帖子现在看起来像这样。 问题答案: 这不是使用AngularJS访问表单数据的方式。表单中的数据应在范围内绑定。 因此,使用一个对象,例如$ scope.formData,它将包含您的所有数据结构,然后应使用ng-model将每个表单元素绑定到此对象。 例如: http://jsfiddle.net/rd13/AvGKj/13/
问题内容: 我正在尝试弄清楚如何解析一些XML(对于Android应用程序),在Java中很难做到这一点似乎很荒谬。似乎需要创建一个具有各种回调(startElement,endElement等)的XML处理程序,然后您必须注意将所有这些数据更改为对象。类似于本教程。 我真正需要的只是将XML文档更改为多维数组,甚至更好的是拥有某种Hpricot处理器。有没有办法做到这一点,还是真的必须在上面的示
我使用以下行对Sqlite查询的行进行循环。 当行数大约为15000时,需要很长时间。空的块需要大约4秒,而有一些代码的
问题内容: 我的桌子上有很多记录(可能超过500 000或1 000 000)。我在此表中添加了一个新列,我需要使用该表中另一列的相应行值为该列中的每一行填充一个值。 我尝试使用单独的事务来选择每100条记录的下一个块并为其更新值,但是例如,要花费数小时来更新Oracle10中的所有记录。 在不使用某些方言特定功能的情况下,在SQL中执行此操作的最有效方法是什么,因此它可在任何地方(Oracle,
问题内容: 最近,我一直在使用嵌套集模型中的废话。我喜欢为几乎所有有用的操作和视图设计查询。我坚持的一件事是如何选择节点的直接子代(并且 仅 选择子代,而不是进一步的子代!)。 老实说,我确实知道一种方法-但它涉及大量的SQL。我敢肯定有一个更直接的解决方案。 问题答案: 您是否阅读过您张贴的文章?在“查找节点的直接下属”标题下 但是,我要做的(这是作弊)是将嵌套集与邻接列表结合在一起-我在表中嵌