380. 两个链表的交叉

380. 两个链表的交叉

 

请写一个程序,找到两个单链表最开始的交叉节点。

样例

样例 1:

输入:

A: a1 → a2

c1 → c2 → c3

B: b1 → b2 → b3

输出:c1

解释:在节点 c1 开始交叉。

样例 2:

输入:

Intersected at 6

1->2->3->4->5->6->7->8->9->10->11->12->13->null

6->7->8->9->10->11->12->13->null

输出: Intersected at 6

解释:begin to intersect at node 6.

挑战

需满足 O(n) 时间复杂度,且仅用 O(1) 内存。

注意事项

  • 如果两个链表没有交叉,返回null。

  • 在返回结果后,两个链表仍须保持原有的结构。

  • 可假定整个链表结构中没有循环。

 

 

 

 

超级巧妙的解,细品

参考https://leetcode-cn.com/problems/intersection-of-two-linked-lists/submissions/

这段代码叫: 无论谁先迈出第一步,对的人,总会相遇。

 

public class Solution {

    /**

     * @param headA: the first list

     * @param headB: the second list

     * @return: a ListNode

     */

    public ListNode getIntersectionNode(ListNode headA, ListNode headB) {

        if(headA == null || headB == null){

            return null;

        }

        

        ListNode a = headA;

        ListNode b = headB;

        while(a != b){

            a = a == null ? headB : a.next;

            b = b == null ? headA : b.next;

        }

        return a;

    }

}

第二种方法: 编译一个链表到结尾,将结尾和其中一条链表链接,形成一个环,然后哦使用找环第一个节点的方法

public class Solution {

    /**

     * @param headA: the first list

     * @param headB: the second list

     * @return: a ListNode

     */

    public ListNode getIntersectionNode(ListNode headA, ListNode headB) {

        if(headA == null || headB == null){

            return null;

        }

        

        //知道A的结尾;

        ListNode tailA = headA;

        while(tailA.next != null){

            tailA = tailA.next;

        }

        tailA.next = headA;

        

        //知道第一个相遇点

        ListNode ans = get(headB);

        tailA.next = null;

        

        return ans;

        

    }

    

    private ListNode get(ListNode head){

        ListNode slow = head;

        ListNode fast = head;

        while(fast != null && fast.next != null){

            slow = slow.next;

            fast = fast.next.next;

            if(fast == slow){

                while(head != slow){

                    head = head.next;

                    slow = slow.next;

                }

                return slow;

            }

        }

        return null;

    }

    

}

第一种方法: 使用set

public class Solution {

    /**

     * @param headA: the first list

     * @param headB: the second list

     * @return: a ListNode

     */

    public ListNode getIntersectionNode(ListNode headA, ListNode headB) {

        if(headA == null || headB == null){

            return null;

        }

        

        Set<ListNode> hashSet = new HashSet<>();

        ListNode nodeA = headA;

        while(nodeA != null){

            hashSet.add(nodeA);

            nodeA = nodeA.next;

        }

        

        ListNode nodeB = headB;

        while(nodeB != null){

            if(hashSet.contains(nodeB)){

                return nodeB;

            }

            nodeB = nodeB.next;

        }

        return null;

    }

}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

时代我西

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值