编写一个程序,找到两个单链表相交的起始节点。
相交为8
法一:
让两个链表都入栈,在把两个栈出栈对比,如果相等就刷新记录,不等不刷新记录,跳出循环即可,这应记录的就是相交的节点。
public ListNode getIntersectionNode(ListNode headA, ListNode headB){
Stack<ListNode> stackA,stackB;
stackA = new Stack<>();
stackB = new Stack<>();
ListNode t = null;
while (headA != null){
stackA.push(headA);
headA = headA.next;
}
while (headB != null){
stackB.push(headB);
headB = headB.next;
}
while (!stackA.isEmpty() && !stackB.isEmpty()){
if (stackA.peek() == stackB.peek()){
t = stackA.pop();
stackB.pop();
}else {
break;
}
}
return t;
}
法二:
遍历链表,分别切换对方头部,就找到了。。
/**
* 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 pA = headA,pB = headB;
// 在这调换一次头指针就行了
while (pA != pB){
pA = pA == null ? headB : pA.next;
pB = pB == null ? headA : pB.next;
}
return pA;
}
}
法三:
先遍历其中一个链表,使其链表指向其表头,构成环;
然后用快慢指针相交则说明有交点;
再用类似于法二的方法,使其中一个节点重新指向不成环的链表的头结点,然后遍历移动指针,再次相交的就是两个单链表相交的起始节点。
public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
if (headA == null || headB == null){
return null;
}
ListNode last = headB;
while (last.next != null){
last = last.next;
}
last.next = headB;
// 设置快慢指针,相交则说明有交点
ListNode fast = headA;
ListNode slow = headA;
// fast 快,所以判断它
while (fast != null && fast.next != null){
fast = fast.next.next;
slow = slow.next;
if (fast == slow){
slow = headA;
while (fast != slow){
fast = fast.next;
slow = slow.next;
}
last.next = null;
return fast;
}
}
// 解开环
last.next = null;
return null;
}