好的,从你发布的图片,你解析两个列表,最小的第一个。使用最小的列表可以维护对以下节点的引用。现在,当您解析第二个列表时,您将对引用进行比较,以查找 Reference [ i ]是 LinkedList [ i ]-> Link 上的引用的位置。这会给出合并点。用图片解释的时间(将值叠加到图片上 OP)。
你有一个链接列表(如下所示的参考文献) :
A->B->C->D->E
您还有第二个链表:
1->2->
With the merged list, the references would then go as follows:
1->2->D->E->
因此,映射第一个“较小”列表(作为合并列表,我们计算的长度为4,主列表为5)
循环遍历第一个列表,维护引用的引用。
The list will contain the following references Pointers { 1, 2, D, E }.
我们现在来看第二个列表:
-> A - Contains reference in Pointers? No, move on
-> B - Contains reference in Pointers? No, move on
-> C - Contains reference in Pointers? No, move on
-> D - Contains reference in Pointers? Yes, merge point found, break.
这可能违反了“每个列表只解析一次”的条件,但是实现了 龟兔算法(用于查找循环列表的合并点和循环长度) ,所以你从列表 A 开始,当你到达最后的 NULL 时,你假装它是一个指向列表 B 开始的指针,从而创建了一个循环列表的外观。然后,算法会准确地告诉你列表 A 下合并的位置(根据维基百科的描述,变量是“ mu”)。
此外,“ lambda”值告诉您列表 B 的长度,如果您愿意,您可以在算法期间计算列表 A 的长度(当您重定向 NULL 链接时)。
Since we don't know the length, we will calculate x and y without additional iterations; you'll see how.
Then, we iterate each list and reverse them while iterating! If both iterators reach the merge point at the same time, then we find it out by mere comparing. Otherwise, one pointer will reach the merge point before the other one.
After that, when the other iterator reaches the merge point, it won't proceed to the common tail. Instead will go back to the former beginning of the list that had reached merge-point before! So, before it reaches the end of the changed list (i.e. the former beginning of the other list), he will make a+b+1 iterations total. Let's call it z+1.
for each item in list a
push pointer to item onto stack_a
for each item in list b
push pointer to item onto stack_b
while (stack_a top == stack_b top) // where top is the item to be popped next
pop stack_a
pop stack_b
// values at the top of each stack are the items prior to the merged item
Head A 0x7fffb2f3c4b0
0x214f010
0x214f030
0x214f050
0x214f070
0x214f090
0x214f0f0
0x214f110
0x214f130
0x214f150
0x214f170
Head B 0x7fffb2f3c4a0
0x214f0b0
0x214f0d0
0x214f0f0
0x214f110
0x214f130
0x214f150
0x214f170
Note becase I had aligned the node structure, so when malloc() a node, the address is aligned w/ 16 bytes, see the least 4 bits.
The least bits are 0s, i.e., 0x0 or 000b.
因此,如果您也是在相同的特殊情况下(对齐的节点地址) ,您可以使用这些至少4位。
For example when travel both lists from head to tail, set 1 or 2 of the 4 bits of the visiting node address, that is, set a flag;
lenA = count(listA) //iterates list A
lenB = count(listB) //iterates list B
ptrA = listA
ptrB = listB
//now we adjust either ptrA or ptrB so that they are equally far from the end
while(lenA > lenB):
ptrA = ptrA->next
lenA--
while(lenB > lenA):
prtB = ptrB->next
lenB--
while(ptrA != NULL):
if (ptrA == ptrB):
return ptrA //found merge point
ptrA = ptrA->next
ptrB = ptrB->next
this solution iterates each list only once...no modification of list required too..though you may complain about space..
1)基本上可以在 list1中迭代,并将每个节点的地址存储在一个数组中(该数组存储无符号 int 值)
2)然后迭代 list2,对于每个节点的地址——-> ,在数组中搜索,找到匹配的或不匹配的... ... 如果找到匹配的,那么这就是合并节点
//pseudocode
//for the first list
p1=list1;
unsigned int addr[];//to store addresses
i=0;
while(p1!=null){
addr[i]=&p1;
p1=p1->next;
}
int len=sizeof(addr)/sizeof(int);//calculates length of array addr
//for the second list
p2=list2;
while(p2!=null){
if(search(addr[],len,&p2)==1)//match found
{
//this is the merging node
return (p2);
}
p2=p2->next;
}
int search(addr,len,p2){
i=0;
while(i<len){
if(addr[i]==p2)
return 1;
i++;
}
return 0;
}
步骤1: 查找两个列表的长度
步骤2: 找到差异并移动带有差异的最大列表
步骤3: 现在两个列表将处于相似的位置。
Step 4 : Iterate through list to find the merge point
//Psuedocode
def findmergepoint(list1, list2):
lendiff = list1.length() > list2.length() : list1.length() - list2.length() ? list2.lenght()-list1.lenght()
biggerlist = list1.length() > list2.length() : list1 ? list2 # list with biggest length
smallerlist = list1.length() < list2.length() : list2 ? list1 # list with smallest length
# move the biggest length to the diff position to level both the list at the same position
for i in range(0,lendiff-1):
biggerlist = biggerlist.next
#Looped only once.
while ( biggerlist is not None and smallerlist is not None ):
if biggerlist == smallerlist :
return biggerlist #point of intersection
return None // No intersection found
Use Map or Dictionary to store the addressess vs value of node. if the address alread exists in the Map/Dictionary then the value of the key is the answer.
我是这么做的:
logic : make all the integer of list1 to negative. Then walk through the list2, till you get a negative integer. Once found => take it, change the sign back to positive and return.
static int findMergeNode(SinglyLinkedListNode head1, SinglyLinkedListNode head2) {
SinglyLinkedListNode current = head1; //head1 is give to be not null.
//mark all head1 nodes as negative
while(true){
current.data = -current.data;
current = current.next;
if(current==null) break;
}
current=head2; //given as not null
while(true){
if(current.data<0) return -current.data;
current = current.next;
}
}
int FindMergeNode(Node headA, Node headB) {
Node currentA = headA;
Node currentB = headB;
// Do till the two nodes are the same
while (currentA != currentB) {
// If you reached the end of one list start at the beginning of the other
// one currentA
if (currentA.next == null) {
currentA = headA;
} else {
currentA = currentA.next;
}
// currentB
if (currentB.next == null) {
currentB = headB;
} else {
currentB = currentB.next;
}
}
return currentB.data;
}