1. 程式人生 > >Leetcode演算法Java全解答--19. 刪除連結串列的倒數第N個節點

Leetcode演算法Java全解答--19. 刪除連結串列的倒數第N個節點

Leetcode演算法Java全解答–19. 刪除連結串列的倒數第N個節點

文章目錄

題目

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

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

進階:
你能嘗試使用一趟掃描實現嗎?

示例:

給定一個連結串列: 1->2->3->4->5, 和 n = 2.
當刪除了倒數第二個節點後,連結串列變為 1->2->3->5.

想法

  1. 空間換時間的做法

用一個長度為n+1的陣列接收節點

不過需要實時更新陣列,有點複雜

時間複雜度為n,空間複雜度為n
2. 遍歷2次法

先迴圈一次,算出長度,不過掃描了2次,

不符合題目

複雜度n/1

  1. 雙指標法

搞2個指標,讓AB指標中間間隔為n+1,這樣A到末尾的時候,B的下一個節點剛好就是要刪掉的東西

複雜度n/1

結果

超過99%的測試案例

時間複雜度:n

空間複雜度:1

總結

遇到連結串列沒有第一時間想到雙指標

空間換時間,雖然可以做出來,但是很操蛋

程式碼

我的答案

   /*
 * Copyright (C), 2015-2018
 * FileName: Solution019
 * Author:   zhao
 * Date:     2018/11/19 21:11
 * Description: 19. 刪除連結串列的倒數第N個節點
 * History:
 * <author>          <time>          <version>          <desc>
 * 作者姓名           修改時間           版本號              描述
 */
package com.lizhaoblog.mid;

import com.lizhaoblog.diynode.ListNode;

/**
 * 〈一句話功能簡述〉<br>
 * 〈19. 刪除連結串列的倒數第N個節點〉
 *
 * @author zhao
 * @date 2018/11/19 21:11
 * @since 1.0.1
 */
public class Solution019 {

    /**************************************
     * 題目
     給定一個連結串列,刪除連結串列的倒數第 n 個節點,並且返回連結串列的頭結點。
     示例:
     給定一個連結串列: 1->2->3->4->5, 和 n = 2.

     當刪除了倒數第二個節點後,連結串列變為 1->2->3->5.
     說明:
     給定的 n 保證是有效的。
     進階:
     你能嘗試使用一趟掃描實現嗎?
     **************************************/

    /**************************************
     *
     * 想法:
     *          1. 空間換時間的做法
     *              用一個長度為n+1的陣列接收節點
     *              不過需要實時更新陣列,有點複雜
     *              時間複雜度為n,空間複雜度為n
     *          2. 遍歷2次法
     *              先迴圈一次,算出長度,不過掃描了2次,不符合題目
     *          3. 雙指標法
     *              搞2個指標,讓AB指標中間間隔為n+1,這樣A到末尾的時候,B的下一個節點剛好就是要刪掉的東西
     *
     * 我的做法
     *      超過99%的測試案例
     *      時間複雜度:n
     *      空間複雜度:1
     * 程式碼執行過程:
     *
     * 總結:
     *      遇到連結串列沒有第一時間想到雙指標
     *      空間換時間,雖然可以做出來,但是很操蛋
     *
     * ***********************************/
    public ListNode removeNthFromEnd(ListNode head, int n) {

        if (head == null || n == 0) {
            return head;
        }

        ListNode ANode = head;
        ListNode BNode = head;

        for (int i = 0; i < n; i++) {
            ANode = ANode.next;
        }
        while (ANode == null) {
            ANode = ANode.next;
            BNode = BNode.next;
        }

        if (n == 1) {
            BNode.next = null;
        } else {
            BNode.next = BNode.next.next;
        }

        return head;
    }

    /**************************************
     * 比我好的答案 better
     * ***********************************/
    public void better() {
    }

}

大佬們的答案

/**************************************
 * 比我好的答案 better
 * ***********************************/
public ListNode better(ListNode head, int n) {
    ListNode dummy = new ListNode(0);
    dummy.next = head;
    int length = 0;
    ListNode first = head;
    while (first != null) {
        length++;
        first = first.next;
    }
    length -= n;
    first = dummy;
    while (length > 0) {
        length--;
        first = first.next;
    }
    first.next = first.next.next;
    return dummy.next;
}

測試用例

@Test
public void test019() {
    // 建立測試案例
    ListNode listNode1 = new ListNode(1);
    ListNode listNode2 = new ListNode(2);
    ListNode listNode3 = new ListNode(3);
    ListNode listNode4 = new ListNode(4);
    ListNode listNode5 = new ListNode(5);
    listNode1.next = listNode2;
    listNode2.next = listNode3;
    listNode3.next = listNode4;
    listNode4.next = listNode5;
    int n1 = 2;

    // 測試案例期望值
    ListNode expResult1 = new ListNode(1);
    ListNode expResult12 = new ListNode(2);
    ListNode expResult13 = new ListNode(3);
    ListNode expResult15 = new ListNode(5);
    expResult1.next = expResult12;
    expResult12.next = expResult13;
    expResult13.next = expResult15;

    // 執行方法
    Solution019 solution019 = new Solution019();
    ListNode result1 = solution019.removeNthFromEnd(listNode1, n1);

    // 判斷期望值與實際值
    Assert.assertEquals(expResult1.toArray(), result1.toArray());
}

其他

程式碼託管碼雲地址:https://gitee.com/lizhaoandroid/LeetCodeAll.git

檢視其他內容可以點選專欄或者我的部落格哈:https://blog.csdn.net/cmqwan

“大佬們的答案” 標籤來自leetcode,侵權請聯絡我進行刪改

如有疑問請聯絡,聯絡方式:QQ3060507060