iT邦幫忙

2022 iThome 鐵人賽

DAY 8
0
自我挑戰組

用C語言跑完LeetCode 75 - Part 1系列 第 8

[Day 08] LeetCode 75 - 142. Linked List Cycle II

  • 分享至 

  • xImage
  •  

LeetCode 75 Level 1 - Day 4 Linked List

142. Linked List Cycle II

題目敘述

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.

預設函數

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */
struct ListNode *detectCycle(struct ListNode *head) {
    
}

題目限制

  1. The number of the nodes in the list is in the https://chart.googleapis.com/chart?cht=tx&chl=range%20%5B0%2C%2010%5E4%5D.
  2. https://chart.googleapis.com/chart?cht=tx&chl=-10%5E5%20%3C%3D%20Node.val%20%3C%3D%2010%5E5
  3. pos is -1 or a valid index in the linked-list.

解題過程及程式碼

本題是linked list的第4題,也是這個系列第一次碰到Medium難度,題目給一個linked list,需要檢查list中是否有閉環存在 (如下圖),若有找到閉環則回傳該閉環最開始重複節點的指標 (如下圖②節點的記憶體位置),若不存在閉環也就是list是有終點的話則回傳NULL。

  • 一開始想到的方法是用一個[10000]的陣列來儲存所有走過的節點指標,出現有重複的指標就表示list存在有閉環

    struct ListNode *detectCycle(struct ListNode *head) {
        struct ListNode *ptr_array[10000] = {0};
        struct ListNode *ptr;
        int index = 0;
        int flag = 0;
    
        if (head == NULL) {
            return NULL;
        }
    
        ptr = head;
    
        while (ptr->next != NULL) {
            ptr_array[index] = ptr;
            if (isInArray(ptr_array, ptr->next, index)) {  // 檢查是否已存在陣列裡
                return  ptr->next;
            }
            index++;
            ptr = ptr->next;
        }
        return NULL;
    }
    
    int isInArray(struct ListNode** array, struct ListNode *node, int num) {
        int i;
    
        for (i=0; i<num; i++) {
            if (array[i] == node) {
                return 1;
            }
        }
        return 0;
    }
    
    
  • 後來覺得時間複雜度不太理想,程式需要不停的去查詢陣列,參考網路上的做法,發現可以利用雙指標的方法

  • 雙指標程式碼,時間從240ms降到11ms,效果驚人!

    struct ListNode *detectCycle(struct ListNode *head) {
        struct ListNode *ptr1, *ptr2, *ptr3;
    
        if (head == NULL) {
            return NULL;
        }
    
        ptr1 = head;
        ptr2 = head;
    
        while ((ptr2 != NULL) && (ptr2->next != NULL)) {
            ptr1 = ptr1->next;
            ptr2 = ptr2->next->next;
    
            if (ptr1 == ptr2) {
                ptr3 = head;
                while (ptr1 != ptr3) {
                    ptr1 = ptr1->next;
                    ptr3 = ptr3->next;
                }
                return ptr1;
            }
        }
    
        return NULL;
    }
    

今天就到這裡,謝謝大家!
/images/emoticon/emoticon08.gif


上一篇
[Day 07] LeetCode 75 - 876. Middle of the Linked List
下一篇
[Day 09] LeetCode 75 - 121. Best Time to Buy and Sell Stock
系列文
用C語言跑完LeetCode 75 - Part 130
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言