This article describes several problems and algorithms for intersection and looping on the single-necklace table.
You can also refer to the other articles on the single-necklace list:
Stack of single-necklace table implementations
Four algorithms for reversing a single-necklace table 1. Determine whether two single-link lists intersect 1.1. Problem description
Given two one-way lists, determine whether the linked list intersects (with a common node). 1.2. Algorithm one
The most straightforward solution is to traverse one of the linked lists (linked list one) and traverse through each node in another linked list (list two) to see if there are duplicate nodes, assuming that the length of the two lists is N and M, then the worst progressive time complexity is O (n * m). 1.3. Improvement of Algorithm one
All search nodes may be improved. Algorithm one in the existence of the chain list two scan retrieval, you can take the following ideas to simplify: with the space to change the time: using a tag array to mark the existence of the list two, and then traverse the chain table one, directly using O (1) method to determine whether it is in the chain table two. However, this requires that the contents of the list of two values range less or larger space. When simplified, the time complexity becomes O (n + m), but the space complexity is high. Sort the contents of the list two, reduce the search time by using binary search, and reduce the space complexity to O (Nlog[2] (m)).
Note: The so-called "improvement" here has a premise: the value of the node cannot be duplicated. In other words, the repeating node value must be able to represent the same node. 1.4. Algorithm two
The idea of algorithm two is based on the following two principles: after the intersection of two unidirectional linked lists, it is inevitable that they can no longer be separated. This is very easy to think of, because there is only one direction, once the same node, then the subsequent nodes must be the same. The tail node must be the same after the two list of individual lists intersect. Based on the first principle, it is easy to think of a second.
So, we give this judgment: two linked lists intersect when and only if the tail elements of the two linked lists are the same: assuming two linked lists intersect, it is easy to prove that the tail elements of the two linked list are the same. Reverse proposition: Two linked list of the tail elements of the same time, two linked lists must intersect. (Note: The same node requires more than the same value, but "one", which is the same as the pointer address.) )
The idea of the algorithm is as follows: Traverse the list one to find the tail node pointer. Traverse the list two to find the tail node pointer. If the two tail node pointers are not nullptr and equal, two linked lists intersect. 2. Find the first intersection of the two one-way linked lists that intersect
This problem is an extension of the above problem. By observing the shape of the two linked lists (Y-shaped), we can see that if viewed from the tail, this part of the node from the tail to the first intersection is "aligned" and the previous length is different. Let's also "right-align" the front, so that when you compare nodes, you only need to compare them once instead of traversing another node. Here's how: find the length of the two linked lists Len1 and len2. Suppose Len1 > Len2. Let the long list first traverse len1-len2 times. Two linked lists are traversed together, each time deciding whether to traverse to the same node. 2.1. If the list of single necklaces is ring, then how to find the intersection? if the single necklace table has a ring, one without ring, then they can not intersect, (because after the ring, if the other must also have a ring) if the detection of two has a ring (see the following algorithm), then you can find the beginning of the ring, and then the end point here, to find the length of two linked list to this position Len1 and Len2, and then use the above method to solve. 3. Determine if a single necklace list has a ring 1.1. Description of the problem
Given a single list, determine if there is a ring in the list. 1.2. Algorithm one
Iterate through the single-chain table and mark the nodes that have been traversed. Each time it is traversed, it is looked up from the tagged collection, and if the same node is found, the linked list has a ring. The time complexity is O (n^2). Of course, you can also reduce the time complexity by improving the find algorithm, but not to O (n). 1.4. Algorithm two
Use two pointers to traverse a linked list at the same time. Suppose these two pointers are called fast pointer ptrfast and slow pointer ptrslow, respectively.
The slow pointer is traversed in the usual way: every time you traverse it, there is
Ptrslow = Ptrslow Next;
The fast pointer is traversed at a speed of twice times:
Ptrfast = Ptrfast Next;
Imagine: If this list does not have a ring, just like a straight road, the fast side can never be slow to catch up.
However, when there is a ring, this situation is different:
Because the fast pointer enters the ring and keeps looping, the fast pointer and the slow pointer will soon meet.
The time complexity of this method is O (n). 4. Find linked list elements 1.1. Description of the problem
Find the element specified in the list: Find the penultimate element in the linked list. Find the middle element of the linked list. 1.2. Algorithm one
Let's start with an intuitive analysis: to find the penultimate element, it is necessary to know the length of the list, so at least O (n) time is required. Without the use of other space, at this point we can not know the inverse of the k element, so we must re-traverse, so at least need to traverse 2n-k times. This algorithm is already a very good algorithm, it has been difficult to reduce the use of space without the traversal of the case. 1.4. Algorithm two
This algorithm is just more "elegant", in fact there is no change: using two pointers Ptrfirst and Ptrsecond.
For the first question: let two pointers have a K-step traversal of the stride difference so that when the first pointer points to the last, the second pointer is pointing exactly to the reciprocal K. In fact, the number of traversal is the same as the algorithm. Some articles on the Internet mistakenly think this way is more efficient, in fact, there is no too essential change, only the constant change.
Specifically, the first thing is to let Ptrfirst traverse K nodes, two pointers begin to traverse the nodes together.
Similarly, for the second question: Let the ptrfisrt traverse at twice times (see "Fast pointer" and "Slow pointer" section above), when the first pointer traverses to the last node, the second pointer is traversed to the midpoint.
Study Questions
1, how to find the node of the list 1/3 position.
2, how to find the single-linked list of the starting point and length of the ring. (Tip: You can add a single-linked list by adding a one-dimensional marker bit, and the tag bit field is populated by traversal; If a node is found to have been populated, then there is a loop; At this point, this is the starting point of the ring.) Time complexity O (n), spatial complexity O (n). )