【1032】Sharing&链表题模板总结
原创
©著作权归作者所有:来自51CTO博客作者wx62cea850b9e28的原创作品,请联系作者获取转载授权,否则将追究法律责任
1.题目
https://pintia.cn/problem-sets/994805342720868352/problems/994805460652113920 静态链表,找出两条链表的首个公共结点。
2.思路
基础题。最巧妙点在于设一个int型变量flag
,然后2次遍历——第一次遍历第一条链表(全部结点的flag改从false改为true),第二次遍历第二条链表,如果当前结点的flag是true则马上break跳出for循环(千万别忘了break!!),当然也可以直接return就好了。
注意点:
(1)用map容易超时;输出格式用%05d——不足5位的整数的高位补0;
(2)由于scanf
使用%c格式时是可以读入空格的,所以读入当前地址、数据、后继地址时,scanf的格式不能写成%d%c%d,而要写成%d %c %d。
3.代码
#include<cstdio>
#include<iostream>
#include<stdlib.h>
using namespace std;
const int maxn=100010;
struct Node{
char data;
int next;
bool flag;//结点是否在第一条链表中出现
}node[maxn];
int main(){
for(int i=0;i<maxn;i++)
node[i].flag=false;
int s1,s2,n;
int address,next;
scanf("%d%d%d",&s1,&s2,&n);
char data;//数据
for(int i=0;i<n;i++){
scanf("%d %c %d",&address,&data,&next);
node[address].data=data;
node[address].next=next;
}
int p;
for(p=s1;p!=-1;p=node[p].next){
node[p].flag=true;//枚举第一条链表的所有结点,令其出现次数为1
}
for(p=s2;p!=-1;p=node[p].next){
//遍历第2链表,找到第一个已经在第一条链表中出现的结点
if(node[p].flag==true)
break;
}
if(p!=-1){//如果第二条链表还没有到达结尾,说明找到了共用结点
printf("%05\n",p);
}else{
printf("-1\n");
}
system("pause");
}
4.模板总结
(1)定义静态链表。
(2)for循环对静态链表的每个结点的某元素初始化。
(3)遍历链表,计数:
int p=begin,count=0;
while(p!=-1){//-1代表链表结束
XXX=1;
count++;
p=node[p]->next;
}
(4)很多时候题目给出的结点并不都是有效结点(即可能存在不在链表上的结点),对数组进行排序从而把有效结点移到数组左端。
bool cmp(Node a,Node b){
if(a.XXX==-1||b.XXX=-1){
//至少一个结点是无效结点,就把它放到数组后面
return a.XXX>b.XXX;
}else{
//第二级排序
}
}