【剑指offer36 两个链表的第一个公共子节点】

题目描述

输入两个链表,找出它们的第一个公共结点。(注意因为传入数据是链表,所以错误测试数据的提示是用其他方式显示的,保证传入数据是正确的)
 
因为公共节点之后的数据都是一样的,所以如果两个链表不一样长,如果存在公共尾,那么长的链表前一段一定是不匹配的
 
/*
struct ListNode {
    int val;
    struct ListNode *next;
    ListNode(int x) :
            val(x), next(NULL) {
    }
};*/
class Solution {
public:
    ListNode* FindFirstCommonNode(ListNode* pHead1, ListNode* pHead2) {
        /*
        //因为保证数据是正确的  即使到NULL都没有  那么接下来一定是接到另一个链表上了
        //这个方法有点跳  循环了   利用题目的信息保证正确  那就是必有相同的尾部
        ListNode *p1 = pHead1;
        ListNode *p2 = pHead2;
        while(p1!=p2){
            p1 = (p1==NULL ? pHead2 : p1->next);
            p2 = (p2==NULL ? pHead1 : p2->next);
        }
        return p1;
        */
        
        //两个链表的长度  
        int length1=GetLength(pHead1);
        int length2=GetLength(pHead2);
        ListNode* pNode1=pHead1;
        ListNode* pNode2=pHead2;
        //因为必有相同的尾  所以把长的先往后移动差值
        int lengthDif=0;
        if(length1>=length2){
            lengthDif=length1-length2;
            for(int i=0;i<lengthDif;i++)
                pNode1=pNode1->next;
        }
        if(length1<length2){
            lengthDif=length2-length1;
            for(int i=0;i<lengthDif;i++)
                pNode2=pNode2->next;
        }
        //前面舍弃的必定不会有相同的
        //移动完之后 并不是一定就是这么长  还得找到开始相同的地方
        //while((pNode1!=nullptr)&&(pNode2!=nullptr)&&(pNode1->val!=pNode2->val)){
        while(pNode1 != pNode2){ //就算到最后是null 也会相同
            pNode1=pNode1->next;
            pNode2=pNode2->next;
        }
        //不管是null 还是 正常值  都可返回
        ListNode* pCommonNode=pNode1;
        return pCommonNode;

    }
    
     int GetLength(ListNode* pHead){
        ListNode* pNode=pHead;
        int length=0;
        while(pNode!=nullptr){
            length++;
            pNode=pNode->next;
        }
        return length;
    }
};

 

posted @ 2020-06-15 13:19  Stephen~Jixing  阅读(186)  评论(0编辑  收藏  举报