leetcode 160.相交链表
题目描述:
编写一个程序,找到两个单链表相交的起始节点。
如下面的两个链表:
在节点 c1 开始相交。
示例 1:
输入:intersectVal = 8, listA = [4,1,8,4,5], listB = [5,0,1,8,4,5], skipA = 2, skipB = 3
输出:Reference of the node with value = 8
输入解释:相交节点的值为 8 (注意,如果两个列表相交则不能为 0)。从各自的表头开始算起,
链表 A 为 [4,1,8,4,5],链表 B 为 [5,0,1,8,4,5]。
在 A 中,相交节点前有 2 个节点;在 B 中,相交节点前有 3 个节点。
示例 2:
输入:intersectVal = 2, listA = [0,9,1,2,4], listB = [3,2,4], skipA = 3, skipB = 1
输出:Reference of the node with value = 2
输入解释:相交节点的值为 2 (注意,如果两个列表相交则不能为 0)。
从各自的表头开始算起,链表 A 为 [0,9,1,2,4],链表 B 为 [3,2,4]。
在 A 中,相交节点前有 3 个节点;在 B 中,相交节点前有 1 个节点。
示例 3:
输入:intersectVal = 0, listA = [2,6,4], listB = [1,5], skipA = 3, skipB = 2
输出:null
输入解释:从各自的表头开始算起,链表 A 为 [2,6,4],链表 B 为 [1,5]。
由于这两个链表不相交,所以 intersectVal 必须为 0,而 skipA 和 skipB 可以是任意值。
解释:这两个链表不相交,因此返回 null。
解题思路:
1.双指针方法
给出的两个链表不确定长度,所以不能使用对应的下标的方法直接比较,可以定义两个链表的指针,分别指向链表A和链表B,如果链表A指向了NULL,那么让A指向链表B的头部;如果链表B指向了NULL,那么让B指向链表A的头部;这样操作,至少两轮的循环,可以保证两个两步的长度一样长,然后如果发现相同的节点,该节点就是交点,如果没有交点,那么A、B指针会同时等于NULL;
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
ListNode* pA = headA; // 指向A链表的指针
ListNode* pB = headB; // 指向B链表的指针
// 通过循环遍历的方式补齐两个链表的长度;判断节点是否相等,如果相等调出循环。
while(pA != pB){
pA = (pA == NULL ? headB : pA->next); // 判断pA是否指向空,如果是空,指向B,为了可以补齐两个链表的长度
pB = (pB == NULL ? headA : pB->next); // 同pA,pB指针做同样的操作。
}
return pA;
}
};
2.哈希表的方法
建立一个哈希表,用于存储A链表中的每一个节点,key:value设置为 ListNode*:value,value可以是任意值,这里我让value都等于1,那么,在遍历链表B的时候,如果发现哈希表中存在节点,直接返回。
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
// 如果有链表为空,直接返回
if(headA == NULL || headB == NULL){
return NULL;
}
unordered_map<ListNode*, int> nodeMap; // 建立一个哈希表
// 把链表A的节点作为键值存入哈希表中
while(headA){
nodeMap[headA] = 1;
headA = headA->next;
}
// 遍历链表B,判断B中的节点是否存在哈希表中
while(headB){
if(nodeMap[headB] == 1){
return headB; // 如果存在直接返回,就是相交的节点
}
headB = headB->next;
}
// 不存在返回NULL
return NULL;
}
};
欢迎大家关注我的个人公众号,同样的也是和该博客账号一样,专注分享技术问题,我们一起学习进步