查找单向链表的倒数第 k 个元素:答案解释
Finding the kth last element of a singly linked list: answer explanation
当您需要查找单链表的第 k
个最后一个元素时,通常的天真方法是执行两次遍历。第一个找到列表的长度,第二个迭代直到 (length-k)th
元素。
而优化版本利用了两个指针:
p1
引用列表的头部
p2
是 p1
之前的第 k
个元素
这允许我们在 p2
到达列表末尾时 return p1
的元素。
我不明白为什么第二种方法比第一种方法快,因为在这两种情况下我们都有一个指针遍历整个列表,另一个指针遍历 (length-k)th
元素。
是缓存优化的问题吗?
谢谢。
如果您将 p2
恰好 k
个元素保留在 p1
之后,那么它并没有多大帮助,因为您必须一起进行相同数量的遍历。
不过,您可以通过使用更多指针来优化该过程。
当您遍历列表时,假设您记得每个 (k/m)th 位置的指针,对于某些 m。你只需要记住那些指针的最后一个m+1。然后,当你到达列表的末尾时,不要从头开始迭代,而是从你记得的最早的指针开始。它将在 k 和 k + (k/m) 元素之间,所以你只需要将它向前移动 at大多数 k/m 个位置。
考虑非均匀内存访问时间和长度为 n:
的 单链表
- 在计数迭代方法中,对同一节点的访问将是 n 次访问
- 在滞后指针方法中,对同一节点的访问将 k 分开访问
使用LRU缓存(/with each LRU cache level),前者比后者更容易诱发capacity misses
当您需要查找单链表的第 k
个最后一个元素时,通常的天真方法是执行两次遍历。第一个找到列表的长度,第二个迭代直到 (length-k)th
元素。
而优化版本利用了两个指针:
p1
引用列表的头部p2
是p1
之前的第
k
个元素
这允许我们在 p2
到达列表末尾时 return p1
的元素。
我不明白为什么第二种方法比第一种方法快,因为在这两种情况下我们都有一个指针遍历整个列表,另一个指针遍历 (length-k)th
元素。
是缓存优化的问题吗?
谢谢。
如果您将 p2
恰好 k
个元素保留在 p1
之后,那么它并没有多大帮助,因为您必须一起进行相同数量的遍历。
不过,您可以通过使用更多指针来优化该过程。
当您遍历列表时,假设您记得每个 (k/m)th 位置的指针,对于某些 m。你只需要记住那些指针的最后一个m+1。然后,当你到达列表的末尾时,不要从头开始迭代,而是从你记得的最早的指针开始。它将在 k 和 k + (k/m) 元素之间,所以你只需要将它向前移动 at大多数 k/m 个位置。
考虑非均匀内存访问时间和长度为 n:
的 单链表
- 在计数迭代方法中,对同一节点的访问将是 n 次访问
- 在滞后指针方法中,对同一节点的访问将 k 分开访问
使用LRU缓存(/with each LRU cache level),前者比后者更容易诱发capacity misses