【圖解連結串列類面試題】環形連結串列

hixiaoxiaoniao發表於2020-11-11

目錄

題目描述

利用set求解

快慢指標解法


題目描述

題目地址:https://leetcode-cn.com/problems/linked-list-cycle/

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

示例 1:輸入:head = [3,2,0,-4], pos = 1 輸出:true 解釋:連結串列中有一個環,其尾部連線到第二個節點

示例 2:輸入:head = [1,2], pos = 0 輸出:true 解釋:連結串列中有一個環,其尾部連線到第一個節點

示例 3:輸入:head = [1], pos = -1 輸出:false 解釋:連結串列中沒有環

進階:你能用 O(1)(即,常量)記憶體解決此問題嗎?

利用set求解

我們可以利用set這個資料結構來解決這道題,首先定義一個Set。
之後遍歷連結串列的節點,每遍歷一個節點,就將這個節點的元素放入set中,如果這個連結串列沒有環,那麼最終遍歷就結束了。
如果連結串列有環的話,那麼肯定有一個元素會被訪問兩次,當第二次訪問這個元素的時候,set中就有記錄了,這樣就可以判斷出連結串列是否有環了。

 

java實現

public class Solution {
    public boolean hasCycle(ListNode head) {
        Set s = new HashSet();
        //定義一個set,然後不斷遍歷
        while(head!=null) {
        	//只要某個節點在set中出現過,說明遍歷到重複元素了
            if(s.contains(head)) {
                return true;
            }
            s.add(head);
            head = head.next;
        }
        return false;
    }
}

python實現

class Solution(object):
    def hasCycle(self, head):
        #定義一個set,然後不斷遍歷連結串列
        s = set()
        while head:
            #如果某個節點在set中,說明遍歷到重複元素了,也就是有環
            if head in s:
                return True
            s.add(head)
            head = head.next
        return False

快慢指標解法

假設有個圓形的操場,操場上有a和b兩個人,a和b最開始的時候是站在一起的 

假設b的速度是a的一倍,b不停的跑把a甩在身後了

b跑了N圈之後,終於追上a了

按照這個思路,我們可以假設有a和b兩個指標,一個慢一個快,如果連結串列是有環狀的,那麼走的快的那個指標遲早會跟慢指標重合的

java實現

public class Solution {
    public boolean hasCycle(ListNode head) {
        if(head==null || head.next==null) {
            return false;
        }
        //定義兩個指標i和j,i是慢指標,j是快指標
        ListNode i = head;
        ListNode j = head.next;
        while(j!=null && j.next!=null) {
            if(i==j) {
                return true;
            }
            //i每次走一步,j每次走兩步
            i = i.next;
            j = j.next.next;
        }
        return false;
    }
}

python實現

class Solution(object):
	def hasCycle(self, head):
		"""
		:type head: ListNode
		:rtype: bool
		"""
		if not (head and head.next):
			return False
		#定義兩個指標i和j,i為慢指標,j為快指標
		i,j = head,head.next
		while j and j.next:
			if i==j:
				return True
			# i每次走一步,j每次走兩步
			i,j = i.next, j.next.next
		return False

歡迎掃描關注公眾號 有更多圖解的演算法面試題等你哦~

相關文章