题目:相交链表
编写一个程序,找到两个单链表相交的起始节点。
如下面的两个链表:
在节点 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 个节点。
题解:
方法1:暴力解法
step1:如果A或者B为空,直接返回null
step2:遍历A链表;
step3:遍历B链表;
step4:在对应的每一个A的节点都去B中寻找是否有相同的
时间复杂度:O(n*m)
/**
* Definition for singly-linked list.
* function ListNode(val) {
* this.val = val;
* this.next = null;
* }
*/
/**
* @param {ListNode} headA
* @param {ListNode} headB
* @return {ListNode}
*/
var getIntersectionNode = function(headA, headB) {
//暴力解法
if(!headA || !headB) return null
let pA = headA
while(pA){
let pB = headB
while(pB){
if(pA == pB) return pA
pB = pB.next
}
pA = pA.next
}
};
方法2:双指针
step1:如果A链表为空或者B链表为空,则直接返回null;
step2:定义一个指针pA,一个指针pB,分别遍历A链表、B链表
step3:假设A指针较长,B遍历完后,pB指向A链表遍历;
step4:A指针遍历完后,指向B链表遍历
step5:二者相遇,则是所求公共点的
时间复杂度:O(n)
/**
* Definition for singly-linked list.
* function ListNode(val) {
* this.val = val;
* this.next = null;
* }
*/
/**
* @param {ListNode} headA
* @param {ListNode} headB
* @return {ListNode}
*/
var getIntersectionNode = function(headA, headB) {
//双指针
if(!headA || !headB) return null
let pA = headA;
let pB = headB;
while(pA != pB){
//如果A链表,没有遍历完,接着遍历,若遍历完了,遍历B链表,直到二者重合
pA = pA === null ? headB:pA.next;
pB = pB === null ? headA:pB.next;
}
return pA;
};
方法3:设置标记
step1:遍历A链表,给一个节点做上标记;
step2:遍历B链表,判断节点是否有标记,如果有,直接返回
时间复杂度:O(n)
/**
* Definition for singly-linked list.
* function ListNode(val) {
* this.val = val;
* this.next = null;
* }
*/
/**
* @param {ListNode} headA
* @param {ListNode} headB
* @return {ListNode}
*/
var getIntersectionNode = function(headA, headB) {
//标记法
if(!headA || !headB) return null
let pA = headA;
let pB = headB;
while(pA){
pA.flag = true;
pA = pA.next
}
while(pB){
if(pB.flag) return pB;
pB = pB.next;
}
};