【剑指offer】52、两个链表的第一个公共节点

题目

输入两个链表,找出它们的第一个公共结点。

思路一

因为是反向找,所以会想到用栈。将两个链表都压入两个栈,然后反向弹出,找出第一个公共节点。思路很简单

class Solution {
public:
    ListNode* FindFirstCommonNode( ListNode* pHead1, ListNode* pHead2) {
        stack<ListNode*> s1, s2;
        if (pHead1 == nullptr || pHead2 == nullptr)
            return nullptr;
        while (pHead1 != nullptr)
        {
            s1.push(pHead1);
            pHead1 = pHead1->next;
        }
        while (pHead2 != nullptr)
        {
            s2.push(pHead2);
            pHead2 = pHead2->next;
        }
        ListNode* common = nullptr;
        while (s1.size() && s2.size())
        {
            if (s1.top() == s2.top())
                common = s1.top();
            s1.pop();
            s2.pop();
        }
        return common;
    }
};

思路二

链表这种问题往往可以用快慢指针,先统计出两个链表的长度l1,l2

然后让长一点的链表从头节点先走 |l1-l2|,然后两个指针一起走,第一个相同的就是公共节点

class Solution {
public:
    ListNode* FindFirstCommonNode( ListNode* pHead1, ListNode* pHead2) {
        if ( pHead1 == nullptr || pHead2 == nullptr)
            return nullptr;
        int len1 = ListLength(pHead1);
        int len2 = ListLength(pHead2);

        ListNode* longer = pHead1;
        ListNode* shorter = pHead2;

        for (int i = 1; i <= abs(len1 - len2);i++)
            len1 > len2?longer = longer->next: shorter = shorter->next;

        while (longer != shorter && shorter && longer)
        {
            longer = longer->next;
            shorter = shorter->next;
        }
        return longer; // 当两个没有公共节点时,会返回尾结点,正好是nullptr

    }
    int ListLength(ListNode* pHead){
        ListNode* pre = pHead;
        int count = 0;
        while (pre != nullptr)
        {
            count++;
            pre = pre->next;
        }
        return count;
    }
};

原文地址:https://www.cnblogs.com/shiganquan/p/9348410.html

时间: 2024-08-29 18:14:43

【剑指offer】52、两个链表的第一个公共节点的相关文章

剑指offer (37) 两个链表的第一个公共结点

题目:输入两个链表,找出它们的第一个公共结点 如果两个链表有公共结点,那么公共结点一定出现在两个链表的尾部 如果两链表长度不相等,那么达到公共结点的步数就不一致,如何确保 两个链表从头开始遍历,同步达到公共结点? 这是关键所在 如果两链表长度相同,那么就可以同步达到了? 由此,我们就需要 让两个链表长度"相等" 我们假设 两链表长度分别为m和n,且m > n, 那么我们可以在较长链表中 先走 m - n 步,然后 两个链表游标同步走,如果有公共结点,那么就一定同时达到 ListN

【剑指offer】两个链表的第一个公共结点

转载请注明出处:http://blog.csdn.net/ns_code/article/details/26097395 简单题,剑指offer上的第37题,九度OJ上AC. 题目描述: 输入两个链表,找出它们的第一个公共结点. 输入: 输入可能包含多个测试样例.对于每个测试案例,输入的第一行为两个整数m和n(1<=m,n<=1000):代表将要输入的两个链表的元素的个数.接下来的两行,第一行为第一个链表的所有元素,中间用空格隔开.第二行为第二个链表的所有元素,中间用空格隔开. 输出: 对应

剑指offer:两个链表的第一个公共结点

题目描述输入两个链表,找出它们的第一个公共结点. # -*- coding: utf-8 -*- # @Time : 2019-07-12 22:20 # @Author : Jayce Wong # @ProjectName : job # @FileName : findFirstCommonNode.py # @Blog : https://blog.51cto.com/jayce1111 # @Github : https://github.com/SysuJayce class Lis

剑指offer-第五章优化时间和空间效率(两个链表的第一个公共节点)

思路1:要求的是两个链表的第一个公共节点,首先想到的是用栈来存放两个链表,然后依次从栈中抛出,直到最后一个相同的节点为止.但是要用到两个栈,空间复杂度为O(n): 思路2:从头到尾分别遍历两个链表得到链表的长度风别为,len1和len2,求出两者的差值dif,然后现在长的链表上面走dif步,然后同步走剩下的节点,当就可以找到第一个公共节点了. public ListNode findFirstCommonNode(ListNode pHead1,ListNode pHead2){ if(pHea

找到两个链表的第一个公共节点 37

? ? 引言 ? ? 这个问题一种常想到的方法就是两层循环遍历,外层循环遍历链表A,对A中每个节点,遍历链表B,如果在B中找到,说明这个节点是第一个公共节点,但是这样的方法时间复杂为mn,一般是不允采用的 ? ? 分析问题 ? ? 所以我们需要分析更深层次的问题,找到其中的规律,我们如果动手画一下一般的链表图就能够发现两个链表的第一个公共节点之后的样子一定是如下表示(由此可以发现有时候动手是很重要的) ? ? ? ? 可以发现两个链表在第一个节点重合之后不会再分开了 ? ? 简单多说一句不会分开

经典算法学习——打印两个链表的第一个公共节点

求链表的公共节点是一道很经典的算法题,并不是很难.我们需要知道的是,一旦两个链表有一个公共节点的话,那么这两个链表的形状就是一个"Y"型.也就是说,自公共节点之后的所有节点都是一样的.如下: 其实只要看了这幅图,实现就很简单了.首先我们分别遍历两个链表,分别得出他们的长度L1,L2.然后在查找公共节点时,先在长的那个链表中走|L1-L2|步,然后两个链表同时向后进行同步遍历,每走一步时,就判断后面那个节点是否相同.若相同,则找到该第一个公共节点.完整代码上传至 https://gith

37 - 两个链表的第一个公共节点

题目描述: 输入两个链表,找出它们的第一个公共结点. 如:第一个公共节点为值为 6 的节点. 相关题型:在二叉树中找出两个节点的最低公共祖父节点.使用的算法是:找出根到2个节点的路径,然后从根遍历,当最后一个相同的节点,即为最低公共祖父节点. 思路一: 在本题中,如果我们能从最后 1 个节点(如bst中的根) 向前遍历,则很容易找出第一个公共节点,但是单链表只能从前向后遍历.而给定从前到后,如何得到从后向前,可以想到使用先进后出的栈. 因此我们可以用2个栈存储2个链表的节点,然后从栈顶开始逐个比

36.两个链表的第一个公共节点。

题目描述: ??输入两个链表,找出它们的第一个公共结点. 思路分析: ??由于链表的指针只能指向一个节点,所以两个链表相交后,后面的部分完全一样.所以我们的解题思路就是先求出两个链表的长度,设置俩个指针分别指向两个链表的头部.指向较长链表的指针先走两个链表长度差步,然后两个指针同时开始走,当两个指针指向同一个节点时,这个节点就是第一个公共节点. 代码: /* public class ListNode { int val; ListNode next = null; ListNode(int v

两个链表的第一个公共节点

已知有两个链表,他们可能相交于某一点,求出该点. 方法1.对于第一个链表,每访问一个节点,对该节点做标记.访问第二个链表,如果该元素已经访问,则第一个这样的元素就是所求点. 由于两个链表都访问了一遍,因此时间复杂度O(m+n),空间复杂度O(m)或O(n) 方法2.我们定义节点的距离为节点到链表开始所经过的节点数.如果两个链表长度相同,则相交节点其在两个链表上的距离一定相等.对于长度不同的两个链表,我们可以采用对齐的方式,使其向长度短的链表对齐.这样就可以应用上面的思路.具体算法如下: [cpp