输入两个无环的单向链表,找出它们的第一个公共结点,如果没有公共节点则返回空。(注意因为传入数据是链表,所以错误测试数据的提示是用其他方式显示的,保证传入数据是正确的)
数据范围:
要求:空间复杂度
,时间复杂度 )
要求:空间复杂度
例如,输入{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个两个无环的单链表,且是有公共节点的 {1},{2,3},{}{}2个链表没有公共节点 ,返回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;
}
};
/*
public class ListNode {
int val;
ListNode next = null;
ListNode(int val) {
this.val = val;
}
}*/
/**
* 两个链表的第一个公共结点
* 求第一公共节点,本质是让长的链表先走abs(length1-length2)步,
* 后面大家的步调一致,往后找第一个地址相同的 节点,就是题目要求的节点
* @param pHead1
* @param pHead2
* @return
*/
public class Solution {
public ListNode FindFirstCommonNode(ListNode pHead1, ListNode pHead2) {
int lengthHead1 = 0;
ListNode curHead1 = pHead1;
while (curHead1 != null) {
lengthHead1++;
curHead1 = curHead1.next;
}
int lengthHead2 = 0;
ListNode curHead2 = pHead2;
while (curHead2 != null) {
lengthHead2++;
curHead2 = curHead2.next;
}
curHead1 = pHead1;
curHead2 = pHead2;
if (lengthHead1 > lengthHead2) {
int tmp = lengthHead1 - lengthHead2;
while (tmp > 0) {
curHead1 = curHead1.next;
tmp--;
}
} else {
int tmp = lengthHead2 - lengthHead1;
while (tmp > 0) {
curHead2 = curHead2.next;
tmp--;
}
}
while (curHead1 != curHead2) {
curHead1 = curHead1.next;
curHead2 = curHead2.next;
}
return curHead1;
}
} public class Solution {
public ListNode FindFirstCommonNode(ListNode pHead1, ListNode pHead2) {
ListNode p1=pHead1;
ListNode p2=pHead2;
while (p1!=p2){//p1和p2都把两个链表走一遍,长度一样、速度一样,如果有相同的节点一定会碰到
p1=p1==null?pHead2:p1.next;//就算没有交点,p1和p2也会同时为null返回一样的值
p2=p2==null?pHead1:p2.next;
}
return p1;
}
} 公共节点不是数值相同,而是节点相同即节点地址相同
struct ListNode* FindFirstCommonNode(struct ListNode* pHead1, struct ListNode* pHead2 ) {
int lena = 0, lenb = 0;
struct ListNode *ta = pHead1, *tb = pHead2;
while(ta != NULL) {
lena++;
ta = ta->next;
}
while(tb != NULL) {
lenb++;
tb = tb->next;
}
if (lena > lenb)
while(lena-- != lenb)
pHead1 = pHead1->next;
else
while(lena != lenb--)
pHead2 = pHead2->next;
while(pHead1 != pHead2) {
pHead1 = pHead1->next;
pHead2 = pHead2->next;
}
if (pHead1 == pHead2)
return pHead1;
return NULL;
}
/*
public class ListNode {
int val;
ListNode next = null;
ListNode(int val) {
this.val = val;
}
}*/
import java.util.*;
public class Solution {
public ListNode FindFirstCommonNode(ListNode pHead1, ListNode pHead2) {
// 定义一个set集合
HashSet<ListNode> nodeSet = new HashSet<>();
// 顶一个返回节点
ListNode returnNode = null;
// 遍历两个链表
ListNode p1 = pHead1;
while(p1 != null){
nodeSet.add(p1);
p1 = p1.next;
}
ListNode p2 = pHead2;
while(p2 != null){
if(nodeSet.contains(p2)){
returnNode = p2;
break;
}
p2 = p2.next;
}
return returnNode;
}
} public class Solution {
public ListNode FindFirstCommonNode(ListNode pHead1, ListNode pHead2) {
ListNode cur = pHead2;
if(pHead2==null||pHead1==null){
return null;
}
while(pHead2!=null){
ListNode tem = pHead1;
while(tem!=null){
if(tem == pHead2){
return tem;
}else{
tem = tem.next;
}
}
pHead2 = pHead2.next;
}
return null;
} public ListNode FindFirstCommonNode(ListNode pHead1, ListNode pHead2) {
if(pHead1==null||pHead2==null){
return null;
}
ListNode node1 = pHead1;
ListNode node2 = pHead2;
//如果同时出现null,符合2,3种情况
while(node1!=null||node2!=null){
if(node1==null){
node1 = pHead2;
}
else if(node2==null){
node2=pHead1;
}
//第一种情况
if(node1==node2){
return node1;
}
node1=node1.next;
node2=node2.next;
}
return node1;
} ListNode* FindFirstCommonNode( ListNode* pHead1, ListNode* pHead2) {
if(!pHead1||!pHead2) return nullptr;
int num1=0,num2=0;
ListNode* p1=pHead1;
ListNode* p2=pHead2;
while(p1) num1++,p1=p1->next;
while(p2) num2++,p2=p2->next;
int d=num1<num2?num2-num1:num1-num2;
p1=pHead1,p2=pHead2;
if(num2>num1) {
while(d)
p2=p2->next,d--;
}
else{
while(d)
p1=p1->next,d--;
}
while(p1&&p2)
{
if(p1==p2) return p1;
p1=p1->next;
p2=p2->next;
}
return nullptr;
} class Solution {
public:
ListNode* FindFirstCommonNode( ListNode* pHead1, ListNode* pHead2) {
struct ListNode *t1 = pHead1, *t2 = pHead2;
while(t1 != t2){
t1 = t1 ? t1->next : pHead2; //t1遍历完pHead1表之后从pHead2开始遍历
t2 = t2 ? t2->next : pHead1; //t2遍历完pHead2表之后从pHead1开始遍历
}
return t1;
}
}; public class Solution {
public ListNode FindFirstCommonNode(ListNode pHead1, ListNode pHead2) {
if(pHead1 == null || pHead2 == null) {
return null;
}
ListNode p = pHead1, q = pHead2;
while(p != q) {
p = (p == null ? pHead2 : p.next);
q = (q == null ? pHead1 : q.next);
}
return p;
}
} public ListNode FindFirstCommonNode(ListNode pHead1, ListNode pHead2) {
if(pHead1 != null && pHead2 != null){
ListNode x = pHead1;
ListNode y = pHead2;
while(x!=y){
//模拟了一下想象的链表:
// 当x遍历完之后拼接上y链表,pHead2
// 当y遍历完之后拼接上x链表,pHead1
x = (x == null) ? pHead2 : x.next;
y = (y == null) ? pHead1 : y.next;
}
return x;
}
return null;
} /*
struct ListNode {
int val;
struct ListNode *next;
ListNode(int x) :
val(x), next(NULL) {
}
};*/
class Solution {
public:
ListNode* FindFirstCommonNode( ListNode* pHead1, ListNode* pHead2) {
auto p = pHead1;
auto q = pHead2;
while (p != q) {
if (p) p = p->next;
else p = pHead2;
if (q) q = q->next;
else q = pHead1;
}
return p;
}
}; /*
public class ListNode {
int val;
ListNode next = null;
ListNode(int val) {
this.val = val;
}
}*/
public class Solution {
public ListNode FindFirstCommonNode(ListNode pHead1, ListNode pHead2) {
ListNode h1 = pHead1;
ListNode h2 = pHead2;
if(pHead1 == null || pHead2 == null)
return null;
while(h1!=h2){
h1 = h1.next;
h2 = h2.next;
if(h1 != h2){
if(h1 == null)
h1 = pHead2;
if(h2 == null)
h2 = pHead1;
}
}
return h1;
}
} public class Solution {
public ListNode FindFirstCommonNode(ListNode pHead1, ListNode pHead2) {
ListNode head1 = pHead1,head2 = pHead2;
while(head1 != head2){
head1 = head1 == null ? pHead2:head1.next;
head2 = head2 == null ? pHead1:head2.next;
}
return head1;
}
} 最后p1和p2都是空指针,为什么不能返回null,返回null就报错了public class Solution { public ListNode FindFirstCommonNode(ListNode pHead1, ListNode pHead2) { if(pHead1 == null||pHead2 ==null){ return null; } ListNode p1 = pHead1; ListNode p2 = pHead2; while(p1 != p2){ p1 = p1.next; p2 = p2.next; if(p1 == p2){ return p1; } if(p1 == null){ p1 = pHead2; } if(p2 == null){ p2 = pHead1; } } return p1; } }
/* 找出2个链表的长度,然后让长的先走两个链表的长度差,然后再一起走 (因为2个链表用公共的尾部) */ class Solution { public: ListNode* FindFirstCommonNode( ListNode *pHead1, ListNode *pHead2) { int len1 = findListLenth(pHead1); int len2 = findListLenth(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 findListLenth(ListNode *pHead1){ if(pHead1 == NULL) return 0; int sum = 1; while(pHead1 = pHead1->next) sum++; return sum; } ListNode* walkStep(ListNode *pHead1, int step){ while(step--){ pHead1 = pHead1->next; } return pHead1; } };