題目:
給定一個鏈表,刪除鏈表的倒數第 n 個節點,並且返回鏈表的頭結點。
示例:
給定一個鏈表: 1->2->3->4->5, 和 n = 2.
當刪除了倒數第二個節點后,鏈表變為 1->2->3->5.
說明:
給定的 n 保證是有效的。
進階:
你能嘗試使用一趟掃描實現嗎?
看到這個題,我們得有一些思路:
1.刪除的那個節點需要找到,那就需要雙指針pre和index,
2.雙指針開始都是指向頭節點,index先走到比頭節點的大n的地方,
3.然后兩個指針同時往后遍歷,當index的下一個為空時,此時pre指向的就是需要刪除的那一個節點,
4.刪除的這個節點還需要分情況:(1)、它的后續節點不為空,(2)、它的后續為空,
5.若后續不為空就需要后面的去覆蓋它,若為空,就只需要設置為null就可以了。
代碼如下:
/** * Definition for singly-linked list. * public class ListNode { * int val; * ListNode next; * ListNode(int x) { val = x; } * } */ class Solution { public ListNode removeNthFromEnd(ListNode head, int n) { if(null == head){ return null; } if(n <= 0){ return head; } ListNode pre = head; ListNode index = head; ListNode orghead = head; for(int i = 1;i < n ;i++){ //讓i先走n步 index = index.next; if(null == index){ return null; } } while(null != index.next){ //到n的地方,pre也開始遍歷 orghead = pre; pre = pre.next; index = index.next; } //刪除時得考慮刪除節點是否有后續節點 if(null != pre.next){ pre.val = pre.next.val; //有就往前移 pre.next = pre.next.next; }else{ if(null == pre.next){ //沒有后續,只需把它設置為空就可以 return null; } orghead.next = null; } return head; } }
我測試了一下,不判斷它的后續節點是否為空,直接賦值,出現了空指針異常。
不考慮后續節點的代碼:
/** * Definition for singly-linked list. * public class ListNode { * int val; * ListNode next; * ListNode(int x) { val = x; } * } */ class Solution { public ListNode removeNthFromEnd(ListNode head, int n) { ListNode pre = head; ListNode index = head; for(int i = 1;i < n;i++){ index = index.next; if(index == null){ return null; } } while(index != null){ index = index.next; pre = pre.next; } pre.next = pre.next.next; return head; } }
出現的異常: