链表的部分遍历算作链表的 "one pass" 吗?
Does a partial traversal of a linked-list count as "one pass" of the list?
我一直在完成 LeetCode 上的算法挑战,刚刚完成“从列表末尾删除第 N 个节点”。
许多热门答案声称找到了“一次通过”的解决方案,我在下面包含了一个 Java 示例。
请有人解释为什么“while(n-->0) h2=h2.next;”不算作链表的额外传递,因此,使其成为“两次传递”解决方案?
public ListNode RemoveNthFromEnd(ListNode head, int n) {
ListNode h1=head, h2=head;
while(n-->0) h2=h2.next;
if(h2==null)return head.next; // The head need to be removed, do it.
h2=h2.next;
while(h2!=null){
h1=h1.next;
h2=h2.next;
}
h1.next=h1.next.next; // the one after the h1 need to be removed
return head;
}
我查看了对此解决方案和其他解决方案的评论,但找不到答案。同样,一般 Google 搜索也没有给出解释。
提前致谢。
不,这不是一次通过。一次通过是相对于顺序 I/O 机制(通常是磁带)定义的,意味着每条数据最多按顺序读取一次。在这里将链表类比为磁带,这个算法不是一次性的,因为一般来说,一些节点的 next
字段将被 h2=h2.next
读取一次(在任一循环中)并再次被 h1=h1.next
在第二个循环中。
算法不是single pass,但不是因为第一次循环。
第一个循环对 n
个元素执行部分传递。
第二个循环对 l-n
元素执行两次同时部分传递(h2
上的元素与第一个循环中的元素互补)。总共 2l-n
次查找 next
字段。
单通道解决方案可以借助长度为 n
的 FIFO 队列来实现,但这是“隐藏”了部分通道。
我一直在完成 LeetCode 上的算法挑战,刚刚完成“从列表末尾删除第 N 个节点”。
许多热门答案声称找到了“一次通过”的解决方案,我在下面包含了一个 Java 示例。
请有人解释为什么“while(n-->0) h2=h2.next;”不算作链表的额外传递,因此,使其成为“两次传递”解决方案?
public ListNode RemoveNthFromEnd(ListNode head, int n) {
ListNode h1=head, h2=head;
while(n-->0) h2=h2.next;
if(h2==null)return head.next; // The head need to be removed, do it.
h2=h2.next;
while(h2!=null){
h1=h1.next;
h2=h2.next;
}
h1.next=h1.next.next; // the one after the h1 need to be removed
return head;
}
我查看了对此解决方案和其他解决方案的评论,但找不到答案。同样,一般 Google 搜索也没有给出解释。
提前致谢。
不,这不是一次通过。一次通过是相对于顺序 I/O 机制(通常是磁带)定义的,意味着每条数据最多按顺序读取一次。在这里将链表类比为磁带,这个算法不是一次性的,因为一般来说,一些节点的 next
字段将被 h2=h2.next
读取一次(在任一循环中)并再次被 h1=h1.next
在第二个循环中。
算法不是single pass,但不是因为第一次循环。
第一个循环对 n
个元素执行部分传递。
第二个循环对 l-n
元素执行两次同时部分传递(h2
上的元素与第一个循环中的元素互补)。总共 2l-n
次查找 next
字段。
单通道解决方案可以借助长度为 n
的 FIFO 队列来实现,但这是“隐藏”了部分通道。