题目
找两个链表的第一个公共部分的第一个字母的位置
思路一
- 全部还原整个过程,为每一个节点建立结构体,保存地址,后继,数据。
- 为了后面判断哪个是第一个相同的节点,需要在结构体额外定义两个变量。一个为Order,用于在找清楚前后继关系后把他们排好顺序,这样再找第一个相同节点的时候就可以简单一点,初始定义Order为INF,因为后面要用Order排序,不相关的让他们无穷大;一个为times,记录出现的次数
- . 因为整个操作都相关前后继关系,如果用查找的话就太麻烦了,使用静态数组,下标当自己的地址,这样递归向后找的时候就很方便。
- 先读入所有的数据,然后用A的首地址进行初始化(出现的次数,出现的顺序),然后用B的首地址,去times++,这样就能判断哪些节点出现了两次。
- 用Order把A的结点排好序,然后找哪个节点是第一个times > 1的,输出它的地址就行。
#include<cstdio>
#include<algorithm>
#include<vector>
using namespace std;
const int INF = 10000000;
const int MAX = 100100;
struct key {
char data;
int address, next;
int order = INF;
int times = 0;
};
key Data[MAX];
bool cmp(key a, key b) {
return a.order < b.order;
}
int main() {
int addr1, addr2, n;
int tempaddr1, tempaddr2;
char d;
scanf("%d %d %d", &addr1, &addr2, &n);
for (int i = 0; i < n; i++) {
scanf("%d", &tempaddr1);
getchar();
scanf("%c", &d);
scanf("%d", &tempaddr2);
key temp;
temp.address = tempaddr1;
temp.next = tempaddr2;
temp.data = d;
Data[tempaddr1] = temp;
}
int temp = addr1;
int flag = 1;
while (Data[temp].next != -1) {
Data[temp].order = flag++;
Data[temp].times++;
temp = Data[temp].next;
}
Data[temp].order = flag++;
Data[temp].times++;
temp = addr2;
while (Data[temp].next != -1) {
Data[temp].times++;
temp = Data[temp].next;
}
sort(Data, Data + MAX, cmp);
int i;
for (i = 0; i < flag + 1; i++){
if (Data[i].times > 1) break;
}
if (Data[i].times == 1) printf("-1");
else printf("%05d", Data[i].address);
}
注
- 这个代码有一个超时,有一个答案错误。。但是已经得了23分,所以没去纠结他。
- 但客观来讲,上述代码重复浪费了很多资源,比如结构体已经保存了地址但是为了方便却又开了一个很大的数组,用下标来表示他的地址,还有已知前后继关系却还要排序,浪费了很多空间时间。
思路二
- 建立两个数组,一个用于储存后继,一个用于储存出现的次数
- 直接递归向后找,简单很多。
- 整体思路就是边递归边记录。高效利用每一个过程
#include<cstdio>
const int max = 100010;
int next[max];
int times[max];
int main() {
int addr1, addr2, n;
int tempaddr1, tempaddr2;
char d;
scanf("%d %d %d", &addr1, &addr2, &n);
for (int i = 0; i < n; i++) {
scanf("%d %c %d", &tempaddr1, &d, &tempaddr2);
next[tempaddr1] = tempaddr2;
}
while (addr1 != -1) {
times[addr1] = 1;
addr1 = next[addr1];
}
while (addr2 != -1) {
if (times[addr2] == 1) {
printf("%05d", addr2);
return 0;
}
addr2 = next[addr2];
}
printf("-1");
return 0;
}
注
下标代替位置这种方法在链表题中好像都挺好用,代码也简短。