题目
Write a program to find the node at which the intersection of two singly linked lists begins.
For example, the following two linked lists:
A: a1 → a2
↘
c1 → c2 → c3
↗
B: b1 → b2 → b3
begin to intersect at node c1.
Notes:
- If the two linked lists have no intersection at all, return null.
- The linked lists must retain their original structure after the function returns.
- You may assume there are no cycles anywhere in the entire linked structure.
- Your code should preferably run in O(n) time and use only O(1) memory.
我的解法
/**
* 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) {
Stack<ListNode> s1 = new Stack<>();
Stack<ListNode> s2 = new Stack<>();
// 链表节点入栈
while(headA != null){
s1.push(headA);
headA = headA.next;
}
while(headB != null){
s2.push(headB);
headB = headB.next;
}
// 两链表前一个交点
ListNode res = null;
while(!s1.isEmpty() || !s2.isEmpty()){
ListNode t1 = (s1.isEmpty()) ? null : s1.pop();
ListNode t2 = (s2.isEmpty()) ? null : s2.pop();
// 判断两个链表节点是否为同一对象
if(t1 != t2)
return res;
res = t1;
}
return res;
}
}
算法分析:链表节点入栈,然后倒过来比较。
答案解法(很新颖)
/**
* 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) {
// 如果有链表为空,则无交点
if(headA == null || headB == null) return null;
ListNode a = headA;
ListNode b = headB;
// 即使a、b长度不同,它们都遍历一遍后,此时节点距离两链表尾节点的距离相等
while( a != b){
//第一次循环后,节点变成另一链表的头节点
a = a == null? headB : a.next;
b = b == null? headA : b.next;
}
return a;
}
}
算法分析:将两个链表“拼接”起来,比较“拼起来”的“后半部”链表节点,解决长度不一样导致的无法“倒过来同步比较“的问题。