19 刪除鏈表的倒數第N個節點

給定一個鏈表,刪除鏈表的倒數第n個節點,並且返回鏈表的頭結點。

示例:

給定一個鏈表: 1->2->3->4->5, 和 n = 2.

當刪除了倒數第二個節點後,鏈表變爲 1->2->3->5.

說明:
給定的n保證是有效的

解題思路:

  1. 因爲是鏈表不能像數組一樣直接定位,所有必須得遍歷。整體思路是讓前面的指針先移動n步,之後前後指針共同移動直到前面的指針到尾部爲止;
  2. 首先設立預先指針pre,預先指針是一個小技巧,這個套路在鏈表操作中很常見,在第2題中也碰到了;
  3. 設預先指針pre的下一個節點指向head,設前指針爲start,後指針爲end,二者都等於pre
  4. start先向前移動n步;
  5. 之後start和end共同向前移動,此時二者的距離爲n,當start到尾部時,end的位置恰好爲倒數第n個節點
  6. 因爲要刪除該節點,所以要移動到該節點的前一個才能刪除,所以循環結束條件爲start.next != null
  7. 刪除後返回pre.next;
  8. 時間複雜度:O(n)。

代碼實現:

 public ListNode removeNthFromEnd(ListNode head, int n) {
        
        ListNode pre = new ListNode(0);
        pre.next = head;
        ListNode start = pre;
        ListNode end = pre;
        // start節點先後移n爲
        while (n != 0) {
            start = start.next;
            n--;
        }
        // start end節點同時後移
        while (start.next != null) {
            start = start.next;
            end = end.next;
        }
        // 最後倒數第N個節點在end節點後一個節點
        end.next = end.next.next;
        return pre.next;
        
 }

注意:這裏最後返回是pre.next,爲什麼不直接返回head呢,這是因爲head有可能是被刪掉的結點。而pre.next指向的一定是新鏈表的頭指針。
有問題歡迎留言哦

參考:

https://leetcode-cn.com/problems/remove-nth-node-from-end-of-list/solution/

https://draw.mdnice.com/algorithm/19.html

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章