leetcode 160 Intersection of Two Linked Lists

Write a program to find the node at which the intersection of two singly linked lists begins.

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.

给定两个链表,计算其第一个公共节点。

直观的方法是暴力遍历,对于链表A中的每一节点,在链表B中都遍历一遍,算法复杂度为O(m*n),代码如下:

    ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
        ListNode *ret = nullptr;
        if(!headA || !headB)
            return ret;
        ListNode *p_a = headA;
        while(p_a)
        {
            ListNode *p_b = headB;
            while(p_b)
            {
                if(p_a == p_b)
                {
                    ret = p_a;
                    return ret;
                }
                p_b = p_b->next;
            }
            p_a = p_a->next;
        }
        return ret;
    }

对于一个有追求的刷题者,这种解法显然是不合适的。在剑指offer中,分析了几种思路,一种是借助辅助栈来保存所有链表节点,然后根据出栈时进行判断,时间复杂度和空间复杂度都是O(m + n)。我们对链表进行深入分析后可以发现,若有相同节点,则以后的节点都相同,因此可先计算出链表的长度,让较长的那个链表先走长度差步,这样判断以后的节点,即可找出相同的节点,代码如下:

ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
        unsigned int len1 = getListLength(headA);
        unsigned int len2 = getListLength(headB);
        int len_diff = len1 - len2;
        ListNode *p_a = headA, *p_b = headB;
        if(len_diff > 0)
        {
            while(len_diff-- > 0)
            {
                p_a = p_a->next;
            }
        }
        else
        {
            while(len_diff++ < 0)
            {
                p_b = p_b->next;
            }
        }
        
        while(p_a && p_b)
        {
            if(p_a == p_b)
                return p_a;
            else
            {
                p_a = p_a->next;
                p_b = p_b->next;
            }
        }
        
        return nullptr;
    }
    
    unsigned int getListLength(ListNode *head)
    {
        unsigned int ret = 0;
        ListNode *p = head;
        while(p)
        {
            ++ret;
            p = p->next;
        }
        return ret;
    }

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值