zoukankan      html  css  js  c++  java
  • [LeetCode] 160. 相交链表

    题目链接 : https://leetcode-cn.com/problems/intersection-of-two-linked-lists/

    题目描述:

    编写一个程序,找到两个单链表相交的起始节点。

    如下面的两个链表

    在节点 c1 开始相交。

    示例:

    示例 1:

    输入:intersectVal = 8, listA = [4,1,8,4,5], listB = [5,0,1,8,4,5], skipA = 2, skipB = 3
    输出:Reference of the node with value = 8
    输入解释:相交节点的值为 8 (注意,如果两个列表相交则不能为 0)。从各自的表头开始算起,链表 A 为 [4,1,8,4,5],链表 B 为 [5,0,1,8,4,5]。在 A 中,相交节点前有 2 个节点;在 B 中,相交节点前有 3 个节点。
    

    思路:

    思路一:记录一个链表所有点

    最简单的想法就是,把其中一个链表都记录下来, 看另一个链表是不是包含!

    class Solution(object):
        def getIntersectionNode(self, headA, headB):
            """
            :type head1, head1: ListNode
            :rtype: ListNode
            """
            all_A = set()
            while headA:
                all_A.add(headA)
                headA = headA.next
            while headB and headB not in all_A:
                headB = headB.next
            if headB: return headB
            return None
    

    思路二: 需求链表长度

    求出 headAheadB的长度,得到两个链表的长度的差值。接下来让长链表先走差值,然后两个链表一起走,相遇就是相交点!

    代码如下:

    # Definition for singly-linked list.
    # class ListNode(object):
    #     def __init__(self, x):
    #         self.val = x
    #         self.next = None
    
    class Solution(object):
        def getIntersectionNode(self, headA, headB):
            """
            :type head1, head1: ListNode
            :rtype: ListNode
            """
            headA_len = 0
            headB_len = 0
            p_A = headA
            p_B = headB
            # 求出headA, headB的长度
            while p_A or p_B:
                if p_A:
                    headA_len += 1
                    p_A = p_A.next
                if p_B:
                    headB_len += 1
                    p_B = p_B.next
            def helper(headA, headB, headA_len, headB_len):
                diff = headB_len - headA_len
                p_A = headA
                p_B = headB
                # 长链表先走差值
                while diff:
                    diff -= 1
                    p_B = p_B.next
                # 连个链表一起走
                while p_B and p_A:
                    if p_A == p_B:
                        return p_A
                    p_A = p_A.next
                    p_B = p_B.next
                return None
            # 保持headA链表长度小于headB的链表长度
            if headB_len < headA_len :
                return helper(headB, headA, headB_len , headA_len)
            return helper(headA, headB, headA_len, headB_len)
    

    思路二:无需长度[1]

    整体思路:两个链表一起走,当有一个链表到达末尾时候,转到另一个链表开头,再一起一起走(相当于长链表先走了差值)又有一个链表到底末尾,转到另一个链表开头,相遇就是相交点。

    class Solution(object):
        def getIntersectionNode(self, headA, headB):
            """
            :type head1, head1: ListNode
            :rtype: ListNode
            """
            if not headA or not headB: return 
            pa = headA
            pb = headB
            while pa != pb:
                pa = pa.next if pa else headB
                pb = pb.next if pb else headA
            return pa
    

    1. https://leetcode.com/problems/intersection-of-two-linked-lists/discuss/49785/Java-solution-without-knowing-the-difference-in-len! ↩︎

  • 相关阅读:
    各种筛法与莫比乌斯反演
    欧拉函数技巧与学习笔记
    莫比乌斯函数与欧拉函数的单个值的快速求法
    最短路算法总结
    NOI2018网络同步赛游记
    中国剩余定理及其扩展学习笔记
    构造方法的格式
    private关键字
    成员变量和局部变量的区别
    数据加密代码实现
  • 原文地址:https://www.cnblogs.com/powercai/p/11290738.html
Copyright © 2011-2022 走看看