1. 程式人生 > 其它 >力扣-每日一題----刪除連結串列的倒數第N個節點

力扣-每日一題----刪除連結串列的倒數第N個節點

技術標籤:leetcode連結串列連結串列leetcode

題目描述

給你一個連結串列,刪除連結串列的倒數第 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)

連結:https://leetcode-cn.com/problems/remove-nth-node-from-end-of-list
著作權歸領釦網路所有。商業轉載請聯絡官方授權,非商業轉載請註明出處。

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;