How to determine whether a linked list has a ring
Excerpt 141. Circular Linked List
Given a linked list, determine whether there is a ring in the linked list. If there is a node in the linked list, it can be reached again by continuously tracking the next pointer, then there is a ring in the linked list. In order to represent the rings in a given linked list, we use the integer pos to indicate the position where the end of the linked list is connected to the linked list (the index starts from 0). If pos is -1, then there is no ring in the linked list. Note: pos is not passed as a parameter, just to identify the actual situation of the linked list. If there is a ring in the linked list, return true. Otherwise, it returns false.
Method 1: Hash table cache
A unordered_set
recording visited nodes to <ListNode*
as element type, and then traversing the linked list by again hash table O (1) to lookup efficiency. Time complexity O(n)
, space complexityO(n)
class Solution {
public:
bool hasCycle(ListNode* head) {
//基本思想:哈希表,时间复杂度O(n)空间复杂度O(n)
unordered_set<ListNode*> setNode;
while (head != NULL)
{
if (setNode.find(head) == setNode.end())
setNode.insert(head);
else
return true;
head = head->next;
}
return false;
}
};
Method two: fast and slow pointer
Regarding the linked list forming a ring as a runway, (遍历速率)
two pointers with different moving speeds will meet after traversing several times. At this time, it is enough to judge whether the corresponding node of the pointer points to the same address. Time complexity O(n)
and space complexity degreeO(1)
class Solution {
public:
bool hasCycle(ListNode *head) {
if(head == nullptr || head->next == nullptr)
return false;
ListNode* fast = head;
ListNode* slow = head;
while(fast != nullptr && fast->next != nullptr){
fast =fast->next->next;
slow = slow->next;
if(slow == fast){
return true;
}
}
return false;
}
};
How to judge whether two singly linked lists intersect, and the intersection point
Method 1: Compare elements on the same starting line
For real interview questions, take the longest linked list, traverse first abs(lenA - lenB)
, then traverse and compare
class Solution {
public:
ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
int lenA = 0, lenB = 0;
ListNode* nodeA = headA, *nodeB = headB;
while(nodeA){
++lenA;
nodeA = nodeA->next;
}
while(nodeB){
++lenB;
nodeB = nodeB->next;
}
if(lenA >= lenB){
int dif = lenA - lenB;
while(dif--) headA = headA->next;
}
else{
int dif = lenB - lenA;
while(dif--) headB = headB->next;
}
while(headA && headB){
if(headA == headB) return headA;
headA = headA->next;
headB = headB->next;
}
return nullptr;
}
};