记得之前看到过这题,这好像是2011年的408真题,图都一模一样喔
我知道这么写暴力法肯定会有问题,但还是尝试了下,果然最后一个测试点超时了
测试点5超时暴力法(复杂度O(N^2))
# include <iostream>
using namespace std;
int AddrNow[100010];
char Info[100010];
int AddrNxt[100010];
int N;
int main()
{
int start1, start2;
scanf("%d %d %d", &start1, &start2, &N);
if(start1 == start2){
printf("%05d\n", start1);
return 0;
}
for(int i=0;i<N;++i)
scanf("%d %c %d", &AddrNow[i], &Info[i], &AddrNxt[i]);
int i, j, cnt = 0;
for(i=0;i<N;++i){
cnt = 0;
for(j=0;j<N;++j)
if(AddrNxt[j] == AddrNow[i])
cnt++;
if(cnt == 2)
break;
}
if(cnt == 2)
printf("%05d\n", AddrNow[i]);
else
cout << -1;
return 0;
}
于是记得看到过真题的题解的方法,就写了这个方法,完美AC
双指针AC代码复杂度O(max(len1, len2))
# include <iostream>
using namespace std;
struct Node{
char data;
int next;
}node[100010];
int N;
int getLength(int start)
{
int len = 0;
for(int p = start;p != -1;p = node[p].next)
len++;
return len;
}
int main()
{
int start1, start2;
cin >> start1 >> start2 >> N;
for(int i=0;i<N;++i){
int now;
cin >> now;
cin >> node[now].data >> node[now].next;
}
// 获取两个链表的长度
int len1 = getLength(start1);
int len2 = getLength(start2);
int p = start1, q = start2; // p、q是分别指向两只链表的双指针
// 让长度较长的那个链表的指针先走,走到剩下的链表和另一个链表长度相等(就走长了的那一部分)
if(len1 > len2)
for(int i=0;i<len1 - len2;++i)
p = node[p].next;
else
for(int i=0;i<len2 - len1;++i)
q = node[q].next;
// 两个指针同时遍历两个链表,如果遇到相等地址的节点就说明遇到公共部分了,循环结束,输出p或q
while(p != q){
p = node[p].next;
q = node[q].next;
}
// 输出
if(p != -1)
printf("%05d\n", p);
else
cout << -1 << endl;
return 0;
}