牛客刷题 判断两个单链表是否相交

/*
struct ListNode {
	int val;
	struct ListNode *next;
	ListNode(int x) :
			val(x), next(NULL) {
	}
};*/
#include 
class Solution {
public:
    ListNode* FindFirstCommonNode( ListNode* pHead1, ListNode* pHead2) {
        if(pHead1==NULL||pHead2==NULL)
            return NULL;
        int len1=0,len2=0,diff=0;
        ListNode *p=pHead1;
        ListNode *q=pHead2;
        while(p!=NULL)
        {
            len1++;
            p=p->next;
        }
        while(q!=NULL)
        {
            len2++;
            q=q->next;
        }
        diff=len1-len2>0?len1-len2:len2-len1;
        if(len1>len2)
        {
            p=pHead1;q=pHead2;
        }
        if(len1<=len2)
        {
            p=pHead2;q=pHead1;
        }
        for(int i=0;inext;
        }
        while(p!=q)
        {
            p=p->next;
            q=q->next;
        }
        return p;
        /*
        stack s1;
        stack s2;
        ListNode *p=pHead1;
        ListNode *q=pHead2;
        while(p!=NULL)
        {
            s1.push(p);
            p=p->next;
        }
        while(q!=NULL)
        {
            s2.push(q);
            q=q->next;
        }
        bool flag=false;
        while(!s1.empty()&&!s2.empty())
        {
            if(s1.top()==s2.top())
            {
                flag=true;
                s1.pop();
                s2.pop();
                continue;
            }
            else{
                return s1.top()->next;
            }
        }
        if(flag)
        {
            if(!s1.empty())
            {
                return s1.top()->next;
            }
            else if(!s2.empty())
            {
                return s2.top()->next;
            }
            else
                return pHead1;
        }
        return NULL;
        */
        /*
        ListNode *p=pHead1;
        ListNode *q=pHead2;
        for(;p!=NULL;p=p->next)
        {
            for (;q!=NULL;q=q->next)
            {
                if(p->next==q->next)
                {
                    return p->next;
                }
            }
        }
        */
    }
};

写了两种方法   第一种暴力遍历 O(n^2) 牛客控制了内存空间,显示段溢出  ,这种方法显然不行,

第二种方法 使用两个栈,分别入栈两个单链表,然后在栈都不为空的前提下 ,判断栈顶元素是否相等,因为如果两个单链表相交,会呈现一个y字型,那么两个栈的栈顶元素会一样,一直出栈,直到栈顶是不一样的元素,栈顶元素的下一个结点就是两个单链表相交的第一个结点。

牛客刷题 判断两个单链表是否相交_第1张图片

第三种方法比较简单不需要用到栈,先分别记录两个链表的长度,然后算出长度的差值,让长的链表先从头指针移动差值个next,这样两个指针就会指向距离相交结点相同位置的元素,然后一起往后移,第一个一样的那就是相交的第一个结点。

 

完全覆盖测试用例的情况:

1 其中一个链表为空 或者两个都为空  那么肯定不相交

2 两个链表从头结点就开始相交,那么栈会同时出空,返回头结点就是第一个相交的结点。

3 两个栈都没有出空,遇到了第一个栈顶元素不一样的,返回栈顶元素的下一个结点。

4 两个链表从头到尾都没有相交,那么再判断第一个栈顶元素就可以返回 空。

5 一个链表 是另一个链表的一部分,就是第一个链表从头结点就开始跟第二个链表相交,这时候,其中一个栈会因为 出空而退出循环,要继续判断,返回不为空的那个栈的栈顶元素 的下一个结点。

你可能感兴趣的:(数据结构)