PAT 1032

题目

找两个链表的第一个公共部分的第一个字母的位置

思路一

  1. 全部还原整个过程,为每一个节点建立结构体,保存地址,后继,数据。
  2. 为了后面判断哪个是第一个相同的节点,需要在结构体额外定义两个变量。一个为Order,用于在找清楚前后继关系后把他们排好顺序,这样再找第一个相同节点的时候就可以简单一点,初始定义Order为INF,因为后面要用Order排序,不相关的让他们无穷大;一个为times,记录出现的次数
  3. . 因为整个操作都相关前后继关系,如果用查找的话就太麻烦了,使用静态数组,下标当自己的地址,这样递归向后找的时候就很方便。
  4. 先读入所有的数据,然后用A的首地址进行初始化(出现的次数,出现的顺序),然后用B的首地址,去times++,这样就能判断哪些节点出现了两次。
  5. 用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);
}

  1. 这个代码有一个超时,有一个答案错误。。但是已经得了23分,所以没去纠结他。
  2. 但客观来讲,上述代码重复浪费了很多资源,比如结构体已经保存了地址但是为了方便却又开了一个很大的数组,用下标来表示他的地址,还有已知前后继关系却还要排序,浪费了很多空间时间。

思路二

  1. 建立两个数组,一个用于储存后继,一个用于储存出现的次数
  2. 直接递归向后找,简单很多。
  3. 整体思路就是边递归边记录。高效利用每一个过程
#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;
}


下标代替位置这种方法在链表题中好像都挺好用,代码也简短。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值