求两个链表的第一个公共结点

题目描述:

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

题目分析:

两个链表要有公共结点,就必须要有公共的尾部,从最后一个节点开始,最后一个不相等的节点就是第一个公共的节点。

方法一:使用栈来实现:将两个链表分别push进两个栈中,然后不断的pop,用一个FirCom来记录相等的节点,pop一个值,就更新一下FirCom,最后一次记录的FirCom值就是第一个公共的节点。

AC代码:

struct ListNode {
	int val;
	struct ListNode *next;
	ListNode(int x) :
	val(x), next(NULL) {
	}
};*/

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

方法二:需要先遍历两个链表,求出两个链表的长度,让长的链表先走长度差值步step,再同时走,第一个相等的节点就是第一个公共结点。

/*
struct ListNode {
	int val;
	struct ListNode *next;
	ListNode(int x) :
			val(x), next(NULL) {
	}
};*/

class Solution {
public:
    ListNode* FindFirstCommonNode( ListNode *pHead1, ListNode *pHead2) {
        int len1 = LengthOfList(pHead1);
        int len2 = LengthOfList(pHead2);
        if(len1 > len2)
            pHead1 = WalkStep(pHead1,len1-len2);
        else
            pHead2 = WalkStep(pHead2,len2-len1);
        while(pHead1 != NULL)
        {
            if(pHead1 == pHead2)
                return pHead1;
            pHead1 = pHead1->next;
            pHead2 = pHead2->next;
        }
        return NULL;
        
    }
    int LengthOfList(ListNode* Head)
    {
        if(Head == NULL)
            return 0;
        int count = 0;
        while(Head)
        {
            count++;
            Head = Head->next;
        }
        return count;
    }
    
    ListNode* WalkStep(ListNode* Head, int step)
    {
        while(step--)
        {
            Head = Head->next;
        }
        return Head;
    }
};

方法三:代码简洁,很巧妙的方法。p1,p2两个指针分别指向pHead1,pHead2,p1,p2一直往后走,当p1走到末尾的时候,让p1=pHead2,p1,p2再一直走,当p2走到末尾的时候,让p2=pHead1,此时p1,p2之间的相差的步数就是长度差,再一直走,走到第一个相等的节点就是所求。

/*
struct ListNode {
	int val;
	struct ListNode *next;
	ListNode(int x) :
			val(x), next(NULL) {
	}
};*/
class Solution {
public:
    ListNode* FindFirstCommonNode( ListNode* pHead1, ListNode* pHead2) {
        ListNode* p1 = pHead1;
        ListNode* p2 = pHead2;
        while(p1 != p2)
        {
            if(p1 != NULL)
                p1 = p1->next;
            if(p2 != NULL)
                p2 = p2->next;
            if(p1 != p2)
            {
                if(p1 == NULL)
                    p1 = pHead2;
                if(p2 == NULL)
                    p2 = pHead1;
            }
        }
        return p1;
    }
};

方法四:使用map:map中存节点的指针和一个整型,用来标记节点。遍历一遍pHead1,在map中以ListNode*为索引值建立标记,第二次遍历pHead2,如果cur存在在map中说明是公共结点,第一次遍历到的公共结点,就是第一个公共结点。

/*
struct ListNode {
	int val;
	struct ListNode *next;
	ListNode(int x) :
			val(x), next(NULL) {
	}
};*/

class Solution {
public:
    ListNode* FindFirstCommonNode( ListNode *pHead1, ListNode *pHead2) {
        map<ListNode*,int> map;
        ListNode* cur = pHead1;
        while(cur)
        {
            map[cur] = 1;
            cur = cur->next;
        }
        cur = pHead2;
        while(cur){
            if(map[cur])
                return cur;
            cur = cur->next;
        }
        return NULL;
    }
};

(*^▽^*)

猜你喜欢

转载自blog.csdn.net/Qiana_/article/details/81355557