題目:
給定一個鏈表,刪除鏈表的倒數第 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;
}
}
出現的異常:

