1. 题目解析与核心思路
这道PAT甲级真题"Sharing (25)"考察的是链表操作中的经典问题——寻找两个链表的第一个公共节点。题目通常会给出两个链表的头节点地址,要求找出它们合并的起始点。这类问题在实际开发中非常常见,比如在版本控制系统中查找分支合并点,或是在内存管理中检测内存块的共享情况。
1.1 问题本质理解
题目描述的"Sharing"实际上是指两个链表在某节点后完全重合,形成Y型结构。例如:
code复制List A: 1->2->3->4->5
List B: 9->8->4->5
这里的第一个共享节点是值为4的节点。
1.2 输入输出分析
典型输入格式为:
code复制第一行:两个链表的头节点地址 和 总节点数N
接下来N行:每个节点的地址、数据、下一个节点地址
输出要求给出第一个共享节点的地址,若无共享则输出-1。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 解题方法与算法选择
2.1 暴力解法及其局限
最直观的方法是遍历第一个链表的所有节点,对每个节点都在第二个链表中查找是否存在。这种方法时间复杂度为O(M*N),在PAT考试的数据规模下(通常N≤10^5)会超时。
注意:PAT考试对时间限制严格,一般要求时间复杂度在O(N)或O(NlogN)级别
2.2 哈希表法(O(N)空间)
使用哈希集合存储第一个链表的所有节点地址,然后遍历第二个链表查找第一个存在于集合中的节点。这种方法:
- 时间复杂度:O(M+N)
- 空间复杂度:O(M)或O(N)
虽然能通过,但不是最优解,且不符合题目"25分"分值对应的预期解法。
2.3 双指针法(最优解)
这是本题的标准解法,通过两个指针的巧妙移动实现O(1)空间复杂度:
- 指针pA从链表A头部开始,pB从链表B头部开始
- 同时向前移动,当到达末尾时切换到另一链表的头部
- 当pA == pB时即为第一个公共节点
原理在于:两指针走过的总长度都是A+B,最终会在交点相遇。
3. 具体实现与代码解析
3.1 数据结构定义
使用静态链表表示(PAT题目的常见形式):
c复制struct Node {
char data;
int next;
} nodes[100000];
