1. 程式人生 > 實用技巧 >【轉】linux記憶體管理

【轉】linux記憶體管理

https://leetcode-cn.com/problems/linked-list-cycle/

給定一個連結串列,判斷連結串列中是否有環。

為了表示給定連結串列中的環,我們使用整數 pos 來表示連結串列尾連線到連結串列中的位置(索引從 0 開始)。 如果 pos 是 -1,則在該連結串列中沒有環。

自己寫的方法:

HashSet方法:

public class Solution {
    public boolean hasCycle(ListNode head) {

        ListNode FakeHead=new ListNode(-1);
        FakeHead=head;
        Set
<ListNode> str = new HashSet<ListNode>(); while(FakeHead!=null) { // System.out.println(FakeHead.val); if(!str.contains(FakeHead)) { str.add(FakeHead); FakeHead=FakeHead.next; }else {
return true; } } return false; } }

快慢指標方法:

public class Solution {
    public boolean hasCycle(ListNode head) {
        if(head==null || head.next==null)
        {
            return false;
        }

        ListNode FakeHead=new ListNode(-1);
        ListNode Fast_point
=new ListNode(-1); ListNode Slow_point=new ListNode(-1); Fast_point=head.next; Slow_point=head; while(Fast_point!=null && Fast_point.next!=null) { if(Fast_point!=Slow_point) { Slow_point=Slow_point.next; Fast_point=Fast_point.next.next; } else { return true; } } return false; } }

題解中的方法:

方法一:雜湊表
思路

我們可以通過檢查一個結點此前是否被訪問過來判斷連結串列是否為環形連結串列。常用的方法是使用雜湊表。

演算法

我們遍歷所有結點並在雜湊表中儲存每個結點的引用(或記憶體地址)。如果當前結點為空結點 null(即已檢測到連結串列尾部的下一個結點),那麼我們已經遍歷完整個連結串列,並且該連結串列不是環形連結串列。如果當前結點的引用已經存在於雜湊表中,那麼返回 true(即該連結串列為環形連結串列)。

public boolean hasCycle(ListNode head) {
    Set<ListNode> nodesSeen = new HashSet<>();
    while (head != null) {
        if (nodesSeen.contains(head)) {
            return true;
        } else {
            nodesSeen.add(head);
        }
        head = head.next;
    }
    return false;
}

方法二:雙指標
思路

想象一下,兩名運動員以不同的速度在環形賽道上跑步會發生什麼?

演算法

通過使用具有 不同速度 的快、慢兩個指標遍歷連結串列,空間複雜度可以被降低至 O(1)O(1)。慢指標每次移動一步,而快指標每次移動兩步。

如果列表中不存在環,最終快指標將會最先到達尾部,此時我們可以返回 false。

現在考慮一個環形連結串列,把慢指標和快指標想象成兩個在環形賽道上跑步的運動員(分別稱之為慢跑者與快跑者)。而快跑者最終一定會追上慢跑者。這是為什麼呢?考慮下面這種情況(記作情況 A)- 假如快跑者只落後慢跑者一步,在下一次迭代中,它們就會分別跑了一步或兩步並相遇。

其他情況又會怎樣呢?例如,我們沒有考慮快跑者在慢跑者之後兩步或三步的情況。但其實不難想到,因為在下一次或者下下次迭代後,又會變成上面提到的情況 A。

#快慢指標

public boolean hasCycle(ListNode head) {
    if (head == null || head.next == null) {
        return false;
    }
    ListNode slow = head;
    ListNode fast = head.next;
    while (slow != fast) {
        if (fast == null || fast.next == null) {
            return false;
        }
        slow = slow.next;
        fast = fast.next.next;
    }
    return true;
}