We learn an algorithm, must be to use it, so-called "learning"? So what's the use of judging whether two linked lists intersect? This is because once the two linked lists intersect, it is possible that the program frees all the nodes of the linked list, causing the other node in the linked list lb to be freed, and the user of LB may not know the truth of the fact, which can cause a lot of trouble.
1. Problem analysis
See how the two linked lists intersect in the end, there are several facts about this: (assuming that there is no ring in the list)
(1) Once the two linked lists intersect, then the nodes in the two linked list must have the same address.
(2) Once the two linked lists intersect, the two linked list must be the same node from the intersection node to the tail node.
Analysis out the nature of the problem, then the idea will naturally have.
2. Problem solving
2.1 Hash Solution:
Since even a linked list once intersect, the intersection node must have the same memory address, and different node memory address must be different, then you may wish to use memory address to establish a hash table, so by judging whether there are two linked list memory address of the same node to determine whether the two linked list intersect. This is done by traversing the first linked list and using the address to set up a hash table, traversing the second list to see if the address hash is the same as the node address value in the first table to determine if the two linked lists intersect.
Time complexity O (length1 + length2)
Space complexity O (length1)
Analysis: Time complexity is linear, acceptable, and can be found in the way to the first intersection node, but increases the space complexity of O (length1), which is obviously unsatisfactory.
2.2 Problem transformation
If there are intersecting nodes in the two linked lists, then the second linked list is followed by the first linked list and then traversed from the table header of the second linked list, and if there is a loop, the traversal process must go back to the table head node of the list two. But this approach does not seem to be able to find the first intersect node. What do we do? How can I tell if a ring exists in a linked list and find the start node of the ring?
On the Internet to see a solution: Set two pointers fast and slow, the initial values are pointing to the head, slow each time before further, fast each step forward two steps, if the linked list exists ring, then fast must first enter the ring, and slow after entering the ring, two pointers must meet. (Of course, fast head to tail is null, then a chain-free list), so you can determine whether two linked lists Intersect, the program is as follows:
BOOL Isexitsloop (Slist *head)
{
Slist *slow = head, *fast = head;
while (Fast && fast->next)
{
slow = slow->next;
Fast = fast->next->next;
if (slow = = fast) break;
}
Return! (fast = = NULL | | fast->next = = NULL);
}
below to see how to find the entrance of the ring, when fast and slow meet, slow certainly did not walk through the list, and fast has been circulating in the ring N-Circle (1<=n). Assuming that slow took the S-step, fast took 2s steps (the fast step is also equal to S plus the N-turns on the ring), the ring length is R, then:
2s = s + nr
s= NR
Set the entire chain table length L, the inlet ring and meet point distance is X, the distance from the starting point to the ring entry is a.
A + x = NR
A + x = (n–1) r +r = (n-1) R + l-a
A = (n-1) R + (l–a–x)
(l–a–x) for the distance from the point of encounter to the ring entry point, from the link to the ring entry point equals (n-1) loop inner ring + meet point to the ring entry point (from the point of encounter to traverse the loop back to the entry point of the distance), so we from the link table head, and meet the point of a pointer, each step, Two pointers must meet, and the meeting point is the ring entry point, which is the first of the two linked lists of the same node. The program is described as follows:
slist* Findloopport (slist *head) { slist *slow = head, *fast = head; while (Fast && fast->next) { slow = slow->next; Fast = fast->next->next; if (slow = = fast) break ; } if (fast = = NULL | | fast->next = = NULL) return null; slow = head; while (slow! = fast) { slow = slow->next; Fast = fast->next; } return slow;}
This solution seems to be very sharp, logical reasoning is very good, but the solution of the complexity of the time is how? Slow each time ahead, fast each step forward two steps, so that the number of steps to traverse the end of it??? (ask for explanation)
2.3 Catch the Point
You may want to traverse each list to save the last node, and see if the last node is the same node, in which case the time complexity is O (length1 + length2). Basic also do not need any space, seems to be a good idea oh, then how to find the first intersect node? The length of the linked list can be traversed L1 and L2 (assuming L1>L2) This is the traversal of finding the first linked list in the L1-L2 node, and then the chain table one starts from the first node of the L1-L2, and the chain table two traverses from the second, each time before further, until the first node is found, You can assume that the two linked lists have intersecting nodes, and that point is the first intersecting node (the original is wrong here, thanks to Ider for pointing out the error). The time complexity of this solution is also linear, but if the length of the two linked list is not long, the time complexity is still good.
Here, I know some of the typical solution is said to be done. Welcome to the Great God to provide new ideas!!
3. Problem extension: (think)
Baidu once out of such a written question, in the final analysis also found two linked list whether there is the same node, but the amount of data is very large, that is, the length of the list is billions of dollars. Think about what you should do with it?
@ clear-cut cycle list characteristics