力扣面试150(51/100)
8.9 19. 删除链表的倒数第 N 个结点
给你一个链表,删除链表的倒数第 n
个结点,并且返回链表的头结点。
我的思路:三个指针:pre , cur , next
进行遍历吧,在n - 1的时候要保存pre指针,cur = pre.next next = cur.next
然后pre.next = next cur.next = null
!!!!
是倒数第几个->整数len - n 个,那就先得到总的长度len ,然后遍历找到对应的删除位置,最后进行删除
注意啦!虚拟头节点的使用:代码简洁,不需要考虑删除的什么类型的节点
情况 | 不使用虚拟头节点 | 使用虚拟头节点 |
---|---|---|
删除头节点 | 需要单独判断 if (n === count) | 直接 pre.next = pre.next.next |
删除中间节点 | 正常遍历到前一个节点 | 正常遍历到前一个节点 |
删除尾节点 | 正常遍历到前一个节点 | 正常遍历到前一个节点 |
代码复杂度 | 需要额外条件判断 | 逻辑统一,更简洁 |
我的代码:
var removeNthFromEnd = function(head, n) {const dummy = new ListNode();//使用虚拟头节点,让删除头节点也变得普通dummy.next = head;let cur = head;let count = 0 ;while(cur){count++;cur = cur.next;}cur = dummy;for(let i = 0 ; i < count - n ; i++){cur = cur.next;}cur.next = cur.next.next;return dummy.next;};
总结:
这段代码通过引入虚拟头节点来统一处理链表删除操作,避免了单独判断删除头节点的特殊情况。首先遍历链表计算总长度,然后根据长度和目标位置找到要删除节点的前驱节点,最后通过修改指针完成删除。虚拟头节点的使用让代码逻辑更简洁,无论删除的是头节点、中间节点还是尾节点,都能用同一种方式处理,增强了代码的健壮性和可读性。