LeetCode刷题11-链表-02.07. 链表相交
题目
给你两个单链表的头节点 headA 和 headB ,请你找出并返回两个单链表相交的起始节点。如果两个链表没有交点,返回 null 。
图示两个链表在节点 c1 开始相交:
题目数据保证整个链式结构中不存在环。
注意,函数返回结果后,链表必须 保持其原始结构。
示例:
输入:intersectVal = 8, listA = [4,1,8,4,5], listB = [5,0,1,8,4,5], skipA = 2, skipB = 3
输出:Intersected at ‘8’
解释:相交节点的值为 8 (注意,如果两个链表相交则不能为 0)。从各自的表头开始算起,链表 A 为 [4,1,8,4,5],链表 B 为 [5,0,1,8,4,5]。
在 A 中,相交节点前有 2 个节点;在 B 中,相交节点前有 3 个节点。
提示:
- listA 中节点数目为 m
- listB 中节点数目为 n
- 0 <= m, n <= 3 * 1 0 4 10^4 104
- 1 <= Node.val <= 1 0 5 10^5 105
- 0 <= skipA <= m
- 0 <= skipB <= n
- 如果 listA 和 listB 没有交点,intersectVal 为 0
- 如果 listA 和 listB 有交点,intersectVal == listA[skipA + 1] == listB[skipB + 1]
代码
方式1(模拟出栈):
该方法思路为:
- 获取两个链表长度;
- 初始化栈A与栈B;
- 分布将链表A遍历入栈A,链表B遍历入栈B
- 依次出栈,若出栈A节点与B节点地址值不同,则其next节点为相交节点
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) {
* val = x;
* next = null;
* }
* }
*/
public class Solution {
public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
ListNode dummyNodeA = new ListNode(-1, headA);
ListNode dummyNodeB = new ListNode(-1, headB);
ListNode currNodeA = dummyNodeA;
ListNode currNodeB = dummyNodeB;
int m = 0;
while(currNodeA != null) {
currNodeA = currNodeA.next;
m++;
}
currNodeA = dummyNodeA;
int n = 0;
while(currNodeB != null) {
currNodeB = currNodeB.next;
n++;
}
currNodeB = dummyNodeB;
ListNode[] stackA = new ListNode[m];
ListNode[] stackB = new ListNode[n];
int i = 0;
while(currNodeA != null) {
stackA[i] = currNodeA;
currNodeA = currNodeA.next;
i++;
}
currNodeA = headA;
int j = 0;
while(currNodeB != null) {
stackB[j] = currNodeB;
currNodeB = currNodeB.next;
j++;
}
currNodeB = headB;
i = m - 1;
j = n - 1;
while(i>=0 && j >= 0) {
if(stackA[i] != stackB[j]) {
return stackA[i].next;
}
i--;
j--;
}
return null;
}
}
方式2(末端对齐法):
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) {
* val = x;
* next = null;
* }
* }
*/
public class Solution {
public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
ListNode currNodeA = headA;
ListNode currNodeB = headB;
int m = 0;
while(currNodeA != null) {
currNodeA = currNodeA.next;
m++;
}
int n = 0;
while(currNodeB != null) {
currNodeB = currNodeB.next;
n++;
}
int gap = 0;
// 保持currNodeA指向最长链表
if(m >= n) {
currNodeA = headA;
currNodeB = headB;
gap = m - n;
}else {
currNodeA = headA;
currNodeB = headB;
ListNode tmp = currNodeA;
currNodeA = currNodeB;
currNodeB = tmp;
gap = n - m;
}
// 保持两链表末尾对其
while(gap-- > 0) {
currNodeA = currNodeA.next;
}
while(currNodeA != null && currNodeB != null) {
if(currNodeA == currNodeB) {
return currNodeA;
}else{
currNodeA = currNodeA.next;
currNodeB = currNodeB.next;
}
}
return null;
}
}