leetcode(160):Intersection of Two Linked Lists

本文探讨了如何找出两个单链表开始相交的第一个节点,并提供了两种解决方案。一种通过修改链表结构并检查节点可达性来确定交点;另一种采用Floyd判圈算法,通过将一个链表尾部指向另一个链表头部,高效地找到相交节点。

题目: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.
【note】
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.
题目分析:
第一版:一拿到题目,我对题目的分析,以例子来进行分析,断开a1与a2的连接关系,然后使a1指向b1,从b1如果能遍历到a2,则说明a2在相交的链上,也就是在相同的子链上。依次处理每个A链上的结点,最终得到需要的结果。
对处理的结果是超时,,这个算法的时间复杂度都是O(n^2)了吧。

# 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
        """
        if headA == None or headB == None:
            return None
        node1 = headA
        node2 = node1.next
        while node2:
            node1.next = headB
            if self.isnext(headB, node2):
                node1.next = node2
                return node2
            else:
                node1.next = node2
                node1 = node2
                node2 = node1.next
        return None

    def isnext(self, headB, next_n):
        node = headB
        while node:
            if node == next_n:
                return True
        return False

第二种思路:成立的条件在于二个链表之前有不同的地方,也就是a1,b1应该是不为0的,在这种条件下,我们将B链表的最后节点指向A节点,这样可以利用龟兔赛跑算法来求解,也就是Floyd判圈算法,还可以得到圈的起点,也就是相交点。对于二个链表从头结点开始可能就与另一个链表相同的情形下,是不能利用判圈算法来进行判断的,这个时候需要特殊的进行判断。

# 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
        """
        if headA == None or headB == None:
            return None
        node = headB
        nodea = headA
        while node:
            if node == headA:
                return headA
            if node.next == None:
                while nodea:
                    if nodea == headB:
                        return headB
                    else:
                        nodea = nodea.next
                node.next = headA
                break
            else:
                node = node.next          
        node = self.iscycle(headB)
        nodeB = headB
        while nodeB.next:
            if nodeB.next == headA:
                nodeB.next = None
            else:
                nodeB = nodeB.next
        return node



    def iscycle(self, head):
        if head.next == None or head.next.next == None:
            return None
        fast = head.next.next
        slow = head.next
        while fast:
            if slow == fast:
                slow = head
                while True:
                    if slow == fast:
                        return slow
                    else:
                        slow = slow.next
                        fast = fast.next
            else:
                try:
                    fast = fast.next.next
                    slow = slow.next
                except:
                    return None
        return None

好的,终于把这个问题解决了,看一下大佬们的思路,好像是很简单的说。。

class Solution:
    # @param two ListNodes
    # @return the intersected ListNode
    def getIntersectionNode(self, headA, headB):
        if headA is None or headB is None:
            return None

        pa = headA # 2 pointers
        pb = headB

        while pa is not pb:
            # if either pointer hits the end, switch head and continue the second traversal, 
            # if not hit the end, just move on to next
            pa = headB if pa is None else pa.next
            pb = headA if pb is None else pb.next

        return pa # only 2 ways to get out of the loop, they meet or the both hit the end=None
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值