力扣-每日一題----刪除連結串列的倒數第N個節點
阿新 • • 發佈:2021-01-30
題目描述
給你一個連結串列,刪除連結串列的倒數第 n 個結點,並且返回連結串列的頭結點。
進階:你能嘗試使用一趟掃描實現嗎?
示例 1:
輸入:head = [1,2,3,4,5], n = 2
輸出:[1,2,3,5]
示例 2:
輸入:head = [1], n = 1
輸出:[]
示例 3:
輸入:head = [1,2], n = 1
輸出:[1]
提示:
連結串列中結點的數目為 sz
1 <= sz <= 30
0 <= Node.val <= 100
1 <= n <= sz
來源:力扣(LeetCode)
著作權歸領釦網路所有。商業轉載請聯絡官方授權,非商業轉載請註明出處。
1、兩次掃描
第一次掃描得到連結串列的長度size;
第二次掃描找到倒數第n個節點的前一個節點(為了刪除倒數第n個節點),即,正數第size-n個節點後,進行刪除操作
程式碼
/** * Definition for singly-linked list. * public class ListNode { * int val; * ListNode next; * ListNode() {} * ListNode(int val) { this.val = val; } * ListNode(int val, ListNode next) { this.val = val; this.next = next; } * } */ class Solution { public ListNode removeNthFromEnd(ListNode head, int n) { // // 方法1:兩次掃描 ListNode newHead = new ListNode(0,head); //虛擬頭節點 head = newHead; int size = -1; //第一次掃描 得到連結串列的長度size ListNode cur = head; while (cur.next != null){ cur = cur.next; size++; } cur = head; } }
2、雙指標
定義兩個指標:fast、slow
先讓fast走n個節點,slow指標再開始走
當fast指標走到最後節點時候,slow指標就會指向倒數第n個節點
思考: 刪除需要找到倒數第n個節點的前一個節點,該如何操作?
程式碼:
ListNode dummyNode = new ListNode(0,head);//虛擬頭節點 ListNode fast = head,slow = dummyNode; for(int i=0;i<n;i++){ fast = fast.next; } while(fast != null){ fast = fast.next; slow = slow.next; } //slow是倒數第n個節點的前一個 slow.next = slow.next.next; //刪除 return dummyNode.next;
注意:為了讓找到倒數第n個節點的前一個節點,可以讓fast 指向head,slow指向虛擬頭節點。
這樣再按照上述步驟進行操作,當fast指標走到最後,slow指標是倒數第n個節點的前一個節點
3、棧
遍歷連結串列中的每一個節點,進棧,根據棧“先進後出”的特點,當全部進棧完畢後,出棧n個(迴圈),即倒數第,這樣棧頂節點,就是倒數第n個節點的前一個節點,進行刪除
程式碼
//虛擬頭節點
ListNode dummyNode = new ListNode(0,head);
Stack<ListNode> s = new Stack<>();
ListNode cur = dummyNode;
while(cur != null){
s.push(cur);
cur = cur.next;
}
for(int i=0;i<n;i++){
s.pop();
}
ListNode pre = s.peek();//棧的最頂節點 -- 即倒數第n+1個節點
pre.next = pre.next.next;
return dummyNode.next;