开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 1 天,点击查看活动详情
Day26 2023/02/02
难度:简单
题目
输入两个无环的单向链表,找出它们的第一个公共结点,如果没有公共节点则返回空。(注意因为传入数据是链表,所以错误测试数据的提示是用其他方式显示的,保证传入数据是正确的)
数据范围:n≤1000
要求:空间复杂度 O(1),时间复杂度 O(n)
例如,输入{1,2,3},{4,5},{6,7}时,两个无环的单向链表的结构如下图所示:
可以看到它们的第一个公共结点的结点值为6,所以返回结点值为6的结点。
输入描述:
输入分为是3段,第一段是第一个链表的非公共部分,第二段是第二个链表的非公共部分,第三段是第一个链表和第二个链表的公共部分。 后台会将这3个参数组装为两个链表,并将这两个链表对应的头节点传入到函数FindFirstCommonNode里面,用户得到的输入只有pHead1和pHead2。
返回值描述:
返回传入的pHead1和pHead2的第一个公共节点,后台会打印以该节点为头节点的链表。
示例
输入:{1,2,3},{4,5},{6,7}
返回值:{6,7}
说明:第一个参数{1,2,3}代表是第一个链表非公共部分,第二个参数{4,5}代表是第二个链表非公共部分,最后的{6,7}表示的是2个链表的公共部分
这3个参数最后在后台会组装成为2个两个无环的单链表,且是有公共节点的
思路
这题可以使用双指针法的方式实现,一个指向链表一的头节点(cur1),一个指向链表二的头节点(cur2),分别遍历两个链表来比较节点是否相同,若cur1先为nullptr,则cur1重新指向第二个链表头节点,cur2也是同理。若遍历过程中存在cur1 = cur2,则存在公共节点,并返回,反之则没有。 具体图示:
关键点
- 因为考虑到若存在公共节点但节点前的链表长度不一定相同,仅通过各自遍历一次链表不一定可以判断是否存在公共节点,所以遍历的时候需要特殊处理。
算法实现
c++代码实现-双指针法
public ListNode FindFirstCommonNode(ListNode pHead1, ListNode pHead2) {
ListNode* cur1 = pHead1; //指针1
ListNode* cur2 = pHead2; //指针2
while(cur1 != cur2){
cur1 = (cur1)?pHead2:cur1->next; //若节点为nullptr,就让指针指向另外链表的头节点
cur2 = (cur2)?pHead1:cur2->next;
}
return cur1; //cur1 = cur2,返回公共节点
}
- 时间复杂度 --- 最坏情况下循环两个链表的所有节点,n和m分别为两个链表的长度
- 空间复杂度 --- 没有额外的辅助空间
总结
- 该题不考虑空间复杂的情况下还可以使用哈希法,也挺简单!!!