160. Intersection of Two Linked Lists(python+cpp)

题目:

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.

解释:
寻找两个链表的交点。
解法1:
分别遍历两个链表,得到分别对应的长度。然后求长度的差值,把较长的那个链表向后移动这个差值的个数,然后一一比较即可。(因为要先求链表的长度,所以速度较慢)
python代码:

# 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 not headA or not headB:
            return None
        def listLen(head):
            p=head
            length=0
            while p!=None:
                length+=1
                p=p.next
            return length
        lenA=listLen(headA)
        lenB=listLen(headB)
        lenDif=lenA-lenB
        longList,shortList=headA,headB
        if lenB>lenA:
            lenDif=lenB-lenA
            longList,shortList=headB,headA
        i=0
        while i<lenDif:
            longList=longList.next
            i+=1
        while longList and shortList and longList!=shortList:
            longList=longList.next
            shortList=shortList.next
        return longList

解法2:(更通用的解法)
可以用环的思想来做(为啥是环的思想?当调到另一个链表的头部的时候就是“接上环”的过程),让两条链表分别从各自的开头开始往后遍历,当其中一条遍历到末尾时,我们跳到另一个条链表的开头继续遍历。两个指针最终会相等,而且只有两种情况:
1.在交点处相遇
2.在各自的末尾的空节点处相等(一定要指到链尾的空结点再停止哦,不要指到最后一个结点就停止~)。
因为两个指针走过的路程相同:
如果两个链表不重叠,则走过的路程长度是两个链表的长度之和
如果两个链表重叠,则走过的路程长度是重叠区域长度加上两个不重叠区域的长度,所以一定会相等。
证明:
A的长度为 a + cB 的长度为 b + c,其中 c 为尾部公共部分长度,可知 a + c + b= b + c + a
当访问 A 链表的指针访问到链表尾部时,令它从链表B 的头部开始访问链表 B;同样地,当访问 B 链表的指针访问到链表尾部时,令它从链表 A 的头部开始访问链表 A。这样就能控制访问 AB 两个链表的指针能同时访问到交点。
python代码:

# Definition for singly-linked list.
# class ListNode(object):
#     def __init__(self, x):
#         self.val = x
#         self.next = None
#解法2
class Solution(object):
    def getIntersectionNode(self, headA, headB):
        """
        :type head1, head1: ListNode
        :rtype: ListNode
        """
        tempA,tempB=headA,headB
        while tempA!=tempB:
            tempA=tempA.next if tempA else headB
            tempB=tempB.next if tempB else headA
        return tempA

c++代码:

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
        ListNode* tmpA=headA;
        ListNode* tmpB=headB;
        while(tmpA!=tmpB)
        {
            tmpA=tmpA?tmpA->next:headB;
            tmpB=tmpB?tmpB->next:headA;
        }
        return tmpA;
    }
};

总结:

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值