【问题】输入两个链表,找出它们的第一个公共结点。(单向无环)
【思路】第一个思路,使用hash_set作为辅助空间,首先遍历第一个链表,将链表每个地址保存到hash_set中,然后再遍历第二个链表,边遍历边查找,如果找到,则返回该节点,否则返回nullptr.
/* struct ListNode { int val; struct ListNode *next; ListNode(int x) : val(x), next(NULL) { } };*/ class Solution { public: ListNode* FindFirstCommonNode( ListNode* pHead1, ListNode* pHead2) { if(pHead1 == nullptr || pHead2 == nullptr) return nullptr; ListNode* cur = pHead1; unordered_set<ListNode*> hash_set; while(cur != nullptr){ hash_set.insert(cur); cur = cur->next; } cur = pHead2; while(cur != nullptr){ if(hash_set.find(cur) != hash_set.end()){ return cur; } cur = cur->next; } return nullptr; } };
第二种思路是不使用额外的辅助空间,直接进行遍历,假设当较短的链表这阵p1遍历完成后,将指针移到长链表的头节点pHead2,等p2也遍历完成后,指向pHead1,此时p1和p2之间的节点数正好两个链表节点数量的差,然后两个指针齐头并进,如果相交,则一定可以找到p1==p2的节点,并返回,否则返回nullptr。
/* 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){ p1 = (p1==NULL ? pHead2 : p1->next); p2 = (p2==NULL ? pHead1 : p2->next); } return p1; } };