链表相交
- LeetCode题目链接
- 卡尔老师代码随想录讲解
- 关键点: 首先想到的是暴力法,选定一个链表从头开始,然后逐个遍历另一个链表的节点是否和第一个链表正被指向节点的 next是否相等,相等则找到了相交节点。而卡尔老师有一个更巧妙的方法,因为相交节点的后面节点必然都一样,所以我们对齐尾部节点,然后让长的节点先移动到短节点的开头位置,两者在一起移动,这样当两个节点的 next 相等我们就找到了相交节点。
- 代码:
暴力法:
/**
* 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) {
let dummyheadA = new ListNode (0,headA)
let dummyheadB = new ListNode (0,headB)
let cura = dummyheadA
let curb = dummyheadB
while (cura.next) {
cura = cura.next
while (curb) {
if (curb.next == cura) {
return cura
}
if(curb.next == null) {
curb = dummyheadB
break;
} else {
curb = curb.next
}
}
}
return null
};
双指针法:
var getIntersectionNode = function(headA, headB) {
let curA = headA
let curB = headB
let countA = 0
let countB = 0
while (curA) {
curA = curA.next
countA++
}
while (curB) {
curB = curB.next
countB++
}
if (countB > countA){
/ /下面交换变量注意加 “分号” ,两个数组交换变量在同一个作用域下时
// 如果不加分号,下面两条代码等同于一条代码: [curA, curB] = [lenB, lenA]
[curA, curB] = [curB, curA];
[countA, countB] = [countB, countA];
}
n = countA-countB
while (n--) {
headA = headA.next
}
while (headA && headA!=headB) {
headA = headA .next;
headB= headB.next;
}
return headA
};
- 注意:
在计算两个链表的长度时应该单独写一个 API - 复杂度分析:
时间:暴力法:O( n 2 n^2 n2),双指针法:O( n n n)
空间:O(1)