一、若是容許修改節點的類結構:node
將節點標上顏色,全部節點初始化爲白色,通過的節點標爲黑色,每次讀取下一個節點,當發現顏色爲黑色的時候(若是沒有環,那每一個都應該是白色的),則斷定爲有環,給出僞代碼實現:
指針
while (node != NULL) { if (node->color == WHITE) { node->color = BLACK; node = node->next; continue; } else { return true; } } return false;
二、若是不容許修改節點類,可是能夠修改節點的值:code
修改節點的值,讓每一個節點都指向一個特定的節點,一樣遍歷整個鏈表,若是發現有一個節點是指向這個特定節點的,那確定有環:it
/** * Definition for singly-linked list. * struct ListNode { * int val; * ListNode *next; * ListNode(int x) : val(x), next(NULL) {} * }; */ class Solution { public: bool hasCycle(ListNode *head) { ListNode *destination = new ListNode(0); while (head != NULL) { ListNode *tmp_next = head->next; if (tmp_next == destination) return true; else head->next = destination; head = tmp_next;; } return false; } };
三、既不容許修改節點類,也不容許修改節點值:io
能夠使用快慢指針來判斷,速度仍是挺不錯的,我算了一下,若是成環部分有n個節點,不成環部分有m個節點,那麼,時間複雜度爲 O (m + m % n) :ast
#ifndef LINKED_LIST_CYCLE_H #define LINKED_LIST_CYCLE_H #include <cstdlib> // Definition for singly-linked list. struct ListNode { int val; ListNode *next; ListNode(int x) : val(x), next(NULL) {} }; class Solution { public: bool hasCycle(ListNode *head) { if (head == NULL) return false; ListNode *fast_ptr = head; ListNode *slow_ptr = head; while (fast_ptr != NULL && fast_ptr->next != NULL) { slow_ptr = slow_ptr->next; fast_ptr = fast_ptr->next->next; if (slow_ptr == fast_ptr) return true; } return false; } }; #endif // LINKED_LIST_CYCLE_H