파이썬 알고리즘 일기 (목록 시리즈) (142)의 원형 연결리스트 II를 _leetcode

목록을 감안할 때, 체인 링의 시작으로 첫 번째 노드를 반환합니다. 체인 비순환 경우는 null를 돌려줍니다.

링 주어진 목록을 표시하려면 목록의 마지막에 연결 우리의 정수 POS는 목록의 위치 (0부터 인덱스 시작)을 나타냅니다. POS가 -1, 반지는이 목록에 없습니다.

설명 : 주어진 목록을 수정하는 것을 허용하지 않습니다.

예 1 :

입력 : 헤드 = 3,2,0, -4] , POS = 1
출력 : 노드 인덱스 1 테일 커넥트는
설명 다음 목록은 제 2 노드에 연결되는 링 테일 부를 갖는다.

예 2 :

입력 : 헤드 = [1,2], POS = 0
출력 : 노드 인덱스 0 테일 커넥트
설명 :리스트의 첫 번째 노드의 테일에 연결되어 고리를 갖는다.

예 3 :

输入:head = [1], pos = -1
输出:no cycle
解释:链表中没有环。

출처 : 숙박 버튼 (LeetCode)
링크 : HTTPS : //leetcode-cn.com/problems/linked-list-cycle-ii

방법에있어서, 요소의 정렬되지 않은 시퀀스의 특성 (세트)의 세트를 이용하여 생략한다. 방문 노드 집합의 존재, 원형 연결리스트의 확장, I 연습

# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, x):
#         self.val = x
#         self.next = None

class Solution:
    def detectCycle(self, head: ListNode) -> ListNode:
        if not head or not head.next:
            return None
        visited = set()
        while(head):
            if head in visited:
                return head
            else:
                visited.add(head)
            head = head.next
        return None

방법 2 : 포인터의 속도. 참조 LeetCode 공식적인 답변의
링크 : HTTPS : //leetcode-cn.com/problems/linked-list-cycle-ii/solution/huan-xing-lian-biao-ii-by-leetcode/
단계 하나 : 목록이 원형 인 경우, 포인터 속도가 느린 단계는 두 배 빠른 속도로 포인터를 이동, 포인터는 항상 링의 노드의 속도를 만날 것입니다. 느린 주자 따라 잡기 위해 빠른 실행 항상 실행에 링에, 상상 해보세요. 그러므로 그것은 링 포인터 목록의 속도를 충족하기 위해 입증했다.

2 단계 : 첫 번째 만남 후, 위치, 시작 위치에 빠르게 포인터에 느린 포인터 여전히 포인트를 발생합니다. 빠른 포인터 변경 사항은 한 단계, 항상 두 번째 속도 포인터 충족 입구 노드를 취할. (하드는 다음 증명하기 위해 할,이 법의 생각하는)

의 image.png

공식 답변 LeetCode에서 사진

F는 링의 입구부터 H는 속도 충족 포인터 위치이다. H, 두 파트 A와 파트 B의 고리로 고리 입구.

경우 큰 고리, + B> F 케이스 :

H 속도 포인터 포인트가 포인터 F + A를 느리게 충족, 그것은 빠른 포인터 링보다 도보 F + A + B + 이동하는 것입니다. 포인터 보낸 슬로우 보행 거리가 빠른 2 반 (F + a)의 포인터 = F + 2A + B, F = B 그래서. 즉 + B = F + A, B = F. 걸어 반지 즉 빠른 1 단계 F.에 위치 포인터 이동을 시작, 느린 포인터 위치 시간, 1 B 단계로 이동, 그들은 입구의 위치에 만족합니다.

반지가 매우 작은 경우, F의 경우 여기서 장거리 :

작은 링, 곧 포인터 n 개의 반지를 갈 수 있습니다. 2 (F + a) = F + A + N (A + B의) = F (N-1) (A + B의) + B.

F의 도보 거리, + B 주위에 바퀴의 많은 여전히 ​​입구와 또 다른 만남에 올 것이다 때문이다.

의견의 증거 :

진동 @로부터  https://leetcode-cn.com/u/zhen-zhi/ 그의 분석 한 것을 링이 큰 경우, A + B> F 케이스.

그림 1 : 느린 포인터 아래로 천천히 n은 입구 링을 갈 때, 빨리 빨리 현재 포인터 위치를 내려와 2N.

도 2 : N 포인터 아래 + B 느린 현재 위치 올, 현재 위치 n을 입구에서 링. 이 때, 포인터가 빠른 느린 포인터를 충족하기 위해, 2 (N + B)를 산책. 신속하게 다시 시작 노드에 대한 포인터를하자, 같은 단계에서 만난 N 입구 링을 갈 수 있습니다.

# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, x):
#         self.val = x
#         self.next = None

class Solution:
    def detectCycle(self, head: ListNode) -> ListNode:
        if not head or not head.next:
            return None
        slow = fast = head
        while(fast.next.next and slow.next):
            fast = fast.next.next
            slow = slow.next
            if not fast.next or not slow.next:
                return None
            if fast == slow:
                cur = slow
                pre = head
                while(cur!=pre):
                    cur = cur.next
                    pre = pre.next
                return cur
        return None

 

게시 44 개 원래 기사 · 원의 칭찬 0 · 조회수 1904

추천

출처blog.csdn.net/weixin_39331401/article/details/104607755