第一次用自己想的简单方法,结果最后一个数据总是通过不了,我推测是可能有不止两个链表,所以找的可能不是第一次出现的共用节点。
#include <stdio.h>
#include <stdlib.h>
#include<iostream>
using namespace std;
const int maxn = 100010;
int main() {
/*address=0代表没有节点指向它,=1代表有一个,=2代表有两个指向它,即输出*/
int address[maxn] = { 0 };
int ans=-1; //answer;
int f1, f2, N; //first addr, N is the number of Node
scanf("%d%d%d\n", &f1, &f2, &N);
if (f1 == f2)//头结点相同
ans = f1;
for (int i = 0; i < N; i++) {
int temp,temp1;
char c;
scanf("%d %c %d", &temp, &c, &temp1);
if (temp1 == -1) //尾节点
continue;
if (address[temp1] == 1)
ans = temp1;
address[temp1]++;
}
if (ans != -1)
printf("%05d\n", ans);
else
printf("-1\n");
return 0;
}
下面是正确的思路,看来偷懒还是有代价的。
查阅liuchuo的博客1,发现思路非常奇特,具体地是:
将所有的节点存在node数组中,并且将flag设置为false,在遍历第一个链表时,将此链表的节点的flag设置为true,在遍历第二个链表时查询节点的flag值,若发现flag为true,这此节点即为要找的共同后缀的起点,在遍历第一个链表的时候,已经将node中属于第一个链表的节点标记出来,当第二个节点访问到true节点的时,表明访问到了既属于第一个链表的节点有属于第二个链表的节点,很容易理解,两个链表的初次交汇点即为共同后缀的起点。
#include <iostream>
using namespace std;
struct {
char key;
int next;
bool flag;
}node[100010];
int main(){
int d1,d2,n;
cin>>d1>>d2>>n;
for(int i=0;i<n;i++){
int t1,t2;
char ch;
cin>>t1>>ch>>t2;
node[t1]={ch,t2,false};
}
for(int i=d1;i!=-1;i=node[i].next) node[i].flag=true;
for(int i=d2;i!=-1;i=node[i].next) {
if(node[i].flag){
printf("%05d",i);
return 0;
}
}
printf("-1");
return 0;
}
原文:https://blog.csdn.net/whutshiliu/article/details/83152717