Eat Study Love

먹고 공부하고 사랑하라

Coding_Practice

Linked List Cycle II[M,Hash Table,Linked List,Two Pointers]

eatplaylove 2024. 8. 7. 12:50

https://leetcode.com/problems/linked-list-cycle-ii/description/

Given the head of a linked list, return the node where the cycle begins. If there is no cycle, return null.

There is a cycle in a linked list if there is some node in the list that can be reached again by continuously following the next pointer. Internally, pos is used to denote the index of the node that tail's next pointer is connected to (0-indexed). It is -1 if there is no cycle. Note that pos is not passed as a parameter.

Do not modify the linked list.

 

Example 1:

Input: head = [3,2,0,-4], pos = 1
Output: tail connects to node index 1
Explanation: There is a cycle in the linked list, where tail connects to the second node.

Example 2:

Input: head = [1,2], pos = 0
Output: tail connects to node index 0
Explanation: There is a cycle in the linked list, where tail connects to the first node.

Example 3:

Input: head = [1], pos = -1
Output: no cycle
Explanation: There is no cycle in the linked list.

 

Constraints:

  • The number of the nodes in the list is in the range [0, 104].
  • -105 <= Node.val <= 105

pos is -1 or a valid index in the linked-list.

Follow up: Can you solve it using O(1) (i.e. constant) memory?

 

아래의 순서로 코딩을 해보는 게 맞는 거 같다.

Python으로 할 순 있으나, C로는 할 수 없는 것이 있지만

C로는 할 수 있는데 Python으로 못 하는 것은 없다.

 

1. C

Python 시험에서 한 번 봤던 유형의 문제다.

코테 얼마 보지도 않았는데, 만났던 친구 또 만나면 너무나 반갑다.

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */
struct ListNode* detectCycle(struct ListNode *head) {
    if(!head||!head->next) return NULL;

    //detect cycle
    struct ListNode* slow = head;
    struct ListNode* fast = head;
    bool cond = false;
    while(fast && fast->next){
        slow = slow->next;
        fast = fast->next->next;
        if(slow==fast){
            cond = true;
            break;
        }
    }
    // No cycle
    if(!cond) return NULL;
    // Yes cycle
    else{
        struct ListNode* temp = head;
        while(temp!=slow){
            temp = temp->next;
            slow = slow->next;
        }
        return temp;
    }
}

 

 

2. C++

Cycle Check + cycle 있을 때 cycle 시작지점 찾기까지 한 iteration에 구현해버렸다.

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    ListNode *detectCycle(ListNode *head) {
        if(!head || !head->next) return nullptr;

        ListNode* curr = head;
        ListNode* slow = head;
        ListNode* fast = head;

        while(fast && fast->next){
            fast = fast->next->next;
            slow = slow->next;
            if(slow == fast){
                while(curr!=slow){
                    curr = curr->next;
                    slow = slow->next;
                }
                return curr;
            }
        }
        return nullptr;
    }
};

 

 

3. Python

 

Memory 안 쓰기! 위와 동일

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

class Solution:
    def detectCycle(self, head: Optional[ListNode]) -> Optional[ListNode]:
        if not head or not head.next : return None
        curr = head
        slow = head
        fast = head
        while fast and fast.next :
            slow = slow.next
            fast = fast.next.next

            if slow == fast :
                while curr != slow :
                    curr = curr.next
                    slow = slow.next
                return slow
        return None

 

#Memory 쓰기

head를 그냥 loop에 써버려서 linked list 부셔버리면서 진행하는 것이다 ㅋㅋ

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

class Solution:
    def detectCycle(self, head: Optional[ListNode]) -> Optional[ListNode]:
        if not head or not head.next : return None
        lst = []
        while head:
            if head in lst : return head
            lst.append(head)
            head=head.next
        return None