https://oj.leetcode.com/problems/remove-nth-node-from-end-of-list/
Given a linked list, remove the nth node from the end of list and return its head.
For example,
Given linked list: 1->2->3->4->5, and n = 2. After removing the second node from the end, the linked list becomes 1->2->3->5.
Note:
Given n will always be valid.
Try to do this in one pass.
解题思路:
首先想到的是,两个游标,除了遍历游标外,始终保留一个他前面的一个游标。每遍历一个节点,往后判断n步,然后看结果是不是空,如果是,就说明这个节点就是要删除的,不然就继续向后找。但还有一种可能,就是1->2->3,n=3,直接要删1。由于上面往后判断n步的时候只有两种可能,要么到了结尾正好为null,要么到了结尾还不是null。如果还没到结尾就null了,说明要删除的是第一个节点,那么直接返回即可。
/** * Definition for singly-linked list. * public class ListNode { * int val; * ListNode next; * ListNode(int x) { * val = x; * next = null; * } * } */ public class Solution { public ListNode removeNthFromEnd(ListNode head, int n) { if(head.next == null && n == 1){ return null; } ListNode returnNode = head; ListNode headNode = head; ListNode tailNode = head.next; while(tailNode != null){ ListNode tempNode = tailNode; for(int i = 0; i < n; i++){ tempNode = tempNode.next; if(tempNode == null && i < n - 1){ return returnNode.next; } } if(tempNode == null){ break; } tailNode = tailNode.next; headNode = headNode.next; } headNode.next = tailNode.next; return returnNode; } }
但原题要求one pass,上面可以勉强说是one,但每次都要往后检查n步。考虑一下,需要吗?事实上,我们只要先用一个node,开始就往后先移动n步,然后用一个节点和他同时开始,这样这个node到结尾的时候,说明前面那个节点就是要处理的了。具体些代码的时候,有些技巧,慢的那个节点始终指向要删除的节点的上一个节点,可以直接用headNode.next = headNode.next.next,便可删除下一个节点。
还有一个情况必须考虑,比如链表1-2-3-4,n=4,开始节点从1往后走4步已经空了,那么证明要删除的是第一个节点,于是直接返回第二个节点即可。由于题目里说给的n始终是有效的,就是说n始终小于等于链表的长度,所以tail为空的情况只可能已经走了n步,不可能走了一半就空了。
/** * Definition for singly-linked list. * public class ListNode { * int val; * ListNode next; * ListNode(int x) { * val = x; * next = null; * } * } */ public class Solution { public ListNode removeNthFromEnd(ListNode head, int n) { if(head.next == null && n == 1){ return null; } ListNode returnNode = head; ListNode headNode = head; ListNode tailNode = head; for(int i = 0; i < n; i++){ tailNode = tailNode.next; if(tailNode == null){ return returnNode.next; } } while(tailNode.next != null){ tailNode = tailNode.next; headNode = headNode.next; } headNode.next = headNode.next.next; return returnNode; } }
这道题开始做的时候,第一个方法很快想出,倒是第二个很简单的方法没想出来,实在不该,瓶颈。