簡體   English   中英

為什么在分區列表時打破兩個列表節點之間的鏈接?

[英]Why breaking the link between two list nodes when partitioning a list?

我試圖解決LeetCode上的分區列表問題。 該問題要求給定目標列表節點的鏈表排序,以便具有比目標小的值的所有列表節點將在目標之前,而它們的原始相對順序保持不變。

我能夠提出一個簡單的算法並通過在線判斷,基本上創建兩個指針並使用它們各自在遍歷列表時鏈接節點< target或>= target。

public ListNode partition(ListNode head, int x) {
    ListNode ptr = head;
    ListNode small = new ListNode(0);
    ListNode big = new ListNode(0);
    ListNode dummy_1 = big;
    ListNode dummy_2 = small;
    int i = 1;
    while (ptr != null) {
        if (ptr.val < x) {
          small.next = ptr;
          small = small.next;
        } else {
          big.next = ptr;
          big = big.next;
        }
        ListNode help = ptr.next;
        ptr.next = null;
        ptr = help;
    }
    small.next = dummy_1.next;
    return dummy_2.next;
}

以下代碼打破了ptrptr.next之間的鏈接,並移動了
ptr到原始的ptr.next

ListNode help = ptr.next;
ptr.next = null;
ptr = help;

我還沒想到的是為什么這個步驟是必要的,因為我們可以將ptr移動到next並稍后使用small.next = ptrbig.next = ptr在while循環中直接更新引用;

但是,當我只使用ptr = ptr.next而不是上面的三行代碼時,在線判斷響應錯誤Memory Limit Exceeded

如果有人能為我解釋,我真的很感激。 什么可能導致內存限制錯誤,因為任何循環列表似乎已經避免?

如果至少有一個引用指向對象,則該對象將不符合垃圾收集的條件。 您可以按照這篇文章建立一個圍繞這個概念的簡要理解

以下是兩種情況都會發生的情況

情況1:

ptr = ptr.next

假設鏈接列表在第一次迭代期間處於以下狀態

在此輸入圖像描述

ptr是高級的,但前面的值為7節點仍然被head引用

在此輸入圖像描述

ptr是先進的,但具有值前面的節點1仍然由它的前一個節點所引用

在此輸入圖像描述

ptr是先進的,但具有值前面的節點3仍然由它的前一個節點所引用

在此輸入圖像描述

它一直持續到循環結束。 如果列表的大小非常大,則不會回收內存。 就像你的判斷所說,它會導致像Memory Limit Exceeded這樣的錯誤

案例2:

    ListNode help = ptr.next;
    ptr.next = null;
    ptr = help;

假設鏈接列表在第一次迭代期間處於以下狀態。

  • help指向ptr指向的下一個節點
  • 在下一步中, ptr重新引用以指向help
  • 因此,先前由ptr (具有值7那個)指向的節點有資格進行垃圾收集
  • 記憶被回收了

在此輸入圖像描述

  • help指向ptr指向的下一個節點
  • 在下一步中, ptr重新引用以指向help
  • 因此,先前由ptr (具有值1那個)指向的節點有資格進行垃圾收集
  • 記憶被回收了

在此輸入圖像描述

  • help指向ptr指向的下一個節點
  • 在下一步中, ptr被重新引用以指向help
  • 因此,先前由ptr (具有值3那個)指向的節點有資格進行垃圾收集
  • 記憶被回收了

在此輸入圖像描述

  • help指向ptr指向的下一個節點
  • 在下一步中, ptr被重新引用以指向help
  • 因此,先前由ptr (具有值2那個)指向的節點有資格進行垃圾收集
  • 記憶被回收了

在此輸入圖像描述

如上所述,只需設置big.next = null即可(我使用netbeans / java運行)。

static ListNode partition(ListNode head, int x) {
    ListNode ptr = head;
    ListNode small = new ListNode(0);
    ListNode big = new ListNode(0);
    ListNode dummy_1 = big;
    ListNode dummy_2 = small;
    while (ptr != null) {
        if (ptr.val < x) {
          small.next = ptr;
          small = small.next;
        } else {
          big.next = ptr;
          big = big.next;
        }
        ptr = ptr.next;
    }
    small.next = dummy_1.next;
    big.next = null;
    return dummy_2.next;
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM