/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) {
* val = x;
* next = null;
* }
* }
*/
class Solution {
ListNode getIntersectionNode(ListNode headA, ListNode headB) {
if(headB==null||headA==null) return null;
int numA=0, numB=0;
ListNode A = headA;
ListNode B = headB;
while (A!=null){
A = A.next;
numA++;
}
while (B!=null){
B = B.next;
numB++;
}
A = headA;
B = headB;
if(numA>numB){
int temp=numA-numB;
while (temp>0){
temp--;
A = A.next;
}
} else if (numA<numB) {
int temp=numB-numA;
while (temp>0){
temp--;
B = B.next;
}
}
while (A!=B){
A = A.next;
B = B.next;
}
return A;
}
}
#python解题
class Solution(object):
def getIntersectionNode(self, headA, headB):
“””
:type head1, head1: ListNode
:rtype: ListNode
“””
if headA is None or headB is None:
return None
A, B = headA, headB
while A != B:
A = A.next if A else headB
B = B.next if B else headA
return A
class Solution:
def getIntersectionNode(self, headA: ListNode, headB: ListNode) -> ListNode:
if not headA or not headB:
return None
l1, l2 = headA, headB
while l1 != l2:
if not l1.next and not l2.next:
return None
l1 = l1.next if l1.next else headB
l2 = l2.next if l2.next else headA
return l1
# Definition for singly-linked list.
# class ListNode(object):
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution(object):
def getIntersectionNode(self, headA, headB):
"""
:type head1, head1: ListNode
:rtype: ListNode
"""
pA, pB = headA, headB
lenA, lenB = 0, 0
while pA:
lenA += 1
pA = pA.next
while pB:
lenB += 1
pB = pB.next
pA, pB = headA, headB
if lenA > lenB:
for i in range(lenA - lenB):
pA = pA.next
else:
for i in range(lenB - lenA):
pB = pB.next
while pA != pB:
pA = pA.next
pB = pB.next
return pA
“`python
这辈子想不到还能这样
class Solution:
def getIntersectionNode(self, headA: ListNode, headB: ListNode) -> ListNode:
if not headA or not headB:
return None
pa = headA
pb = headB
while pa != pb:
if not pa.next and not pb.next:
return
if pa.next:
pa = pa.next
else:
pa = headB
if pb.next:
pb = pb.next
else:
pb=headA
return pa
class Solution {
public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
ListNode A = headA, B = headB;
while (A != B) {
A = A != null ? A.next : headB;
B = B != null ? B.next : headA;
}
return A;
}
}
}
共以下 47 个回答
d打卡成功!
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
ListNode *NodeA = headA;
ListNode *NodeB = headB;
//遍历两个链表,直到链表指向末尾后将链表指向另一个链表的头,继续遍历直到两个节点相等
while(NodeA != NodeB)
{
if(NodeA != nullptr)
{
NodeA = NodeA->next;
}
else
{
NodeA = headB;
}
if(NodeB != nullptr)
{
NodeB = NodeB->next;
}
else
{
NodeB = headA;
}
}
return NodeA;
}
};
时间复杂度为O(m+n),空间复杂度为O(1)。
###C++实现
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
if(headANULL || headBNULL) return NULL;
ListNode tmpA=headA,*tmpB=headB;
while(tmpA!=tmpB){
tmpA=tmpANULL?headB:tmpA->next;
tmpB=tmpBNULL?headA:tmpB->next;
}
return tmpA;
}
};
1.构建A,B
2.A= A.next if A else headB
B= B.next if B else headA
3.return = A
//设置两个链表同时分别移动的两个链表,如果个链表中有公共的节点 则可以返回节点 如果没有则返回空
if(headANULL||headB NULL)
{
return NULL;
}
ListNode *A= headA;
ListNode *B = headB;
while(A!=B)
{
A= A?A->next:headB;
B= B?B->next:headA;
}
return A;
自己写的测试用例和题解
使用的是双指针 长链表长度-短链表长度并移动长链表指针使两者指针共同移动到公共节点即可
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
ListNode *pA = headA, *pB=headB;
while(pA!=pB)
{
pA=pAnullptr? headB : pA->next;
pB=pBnullptr? headA: pB->next;
}
return pA;
}
};
时间复杂度 :O(m+n)
空间复杂度: O(1)
先来个简单的暴力解法(总长 – 指定长度 = 返回位置),据说还有双指针形式(如总长5,指定2,fast跑2剩3,slow跟它同时跑3剩2,slow剩下的刚好为返回长度)
struct node * getInterOneNode(struct node *heada,struct node *headb)
{
int lena=0,lenb=0,tag=0;
struct node * p = heada;
struct node * q = headb;
}
时间复杂度O(m+n),空间复杂度O(1)
交替遍历
class Solution {
ListNode getIntersectionNode(ListNode headA, ListNode headB) {
ListNode A = headA;
ListNode B = headB;
while(headA != headB){
headA = headA != null ? headA.next : B;
headB = headB != null ? headB.next : A;
}
return headA;
}
}
//先将公共节点的意思理解了
//后面才好写解题
//时间复杂度为O(m+n);
//空间复杂度为O(1);
class Solution {
public:
ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
ListNode *a=headA;
ListNode *b=headB;
};
哈希存储法:空间复杂度:o(m),时间复杂度:o(m)
双指针法:空间复杂度:o(1),时间复杂度:o(m+n)
时间复杂度:o(n+m),空间复杂度:o(1)
思路;两个指针同时走,当一个指针为空时,从另一个链表的头指针开始出发,走到最后两个指针如果相等则返回,返回nullptr代表没有相交节点,否则返回节点即为相交节点。
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
if (headA nullptr || headB nullptr) {
return nullptr;
}
ListNode *pa = headA, *pb = headB;
while (pa != pb) {
if (pa != nullptr) pa = pa->next;
else pa = headB;
if (pb != nullptr) pb = pb->next;
else pb = headA;
}
return pa;
}
};
思路:两个指针同时走,当一个指针为空时,则从另一个链表头节点开始出发;然后另一个指针也为空时,也是开始从另一个链表的头节点开始出发
时间复杂度:O(n + m),空间复杂度:O(1)
class Solution {
ListNode getIntersectionNode(ListNode headA, ListNode headB) {
ListNode curA = headA;
ListNode curB = headB;
while(curA != curB) {
if(curA != null) {
curA = curA.next;
} else {
curA = headB;
}
if(curB != null)
curB = curB.next;
else
curB = headA;
}
return curA;
}
}
时间复杂度O(m+n)
空间复杂度O(1)
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
if (headA NULL || headB NULL) {
return NULL;
}
ListNode *a=headA, *b=headB;
while(a!=b){
a=aNULL?headB:a->next;
b=bNULL?headA:b->next;
}
return a;
}
};
时间复杂度O(m+n)空间复杂度O(1)
没有思路,只有暴力遍历的想法。后来直接看的答案的双指针拼接的方法,写出的代码
”’java
//单链表 找到两个链表的第一个公共节点
//l1={2,1,4,3};l2={5,6,7,9,4,3}
//思路:两个链表一个前一个后,组成两个新的链表
//l3={2,1,4,3,5,6,7,9,4,3};
//l4={5,6,7,9,4,3,2,1,4,3}
//l3和l4的最后,可以看见拼接后最后几位相等就是公共节点
//时间复杂度O(n)
public class Solution {
public ListNode getIntersectionNode(ListNode headA, ListNode headB)
{
if(headA null || headB null) return null;
ListNode p1 = headA;
ListNode p2 = headB;
while(p1 != p2) {
// p1 = (p1null ? headB : p1.next);
if(p1 != null) {
p1=p1.next;
}
else {
p1=headB;//开始拼接
}
// p2 = (p2null ? headA : p2.next);
if(p2 != null) {
p2=p2.next;
}
else {
p2=headA;//开始拼接
}
}
return p1;
}
}
先遍历两个链的长度
再使之开始节点都处于同一相对位置
之后逐个比较
注意不是值相等而是节点相等
时间复杂度O(m+n)
空间复杂度O(1)
ListNode getIntersectionNode(ListNode *headA, ListNode *headB) {
int lenA = 0;
int lenB = 0;
if(headA nullptr || headB nullptr){
return nullptr;
}
if(headA headB){
return headA;
}
ListNode p = headA;
while(p){
lenA++;
p=p->next;
}
p = headB;
while(p){
lenB++;
p=p->next;
}
ListNode* pa = headA;
ListNode* pb = headB;
int k = 0;
// listA 长
if(lenA > lenB){
k = lenA – lenB;
while(k){
pa = pa->next;
k–;
}
while(pa && pb && pa != pb){
pa = pa->next;
pb = pb->next;
}
if(pa nullptr){
return nullptr;
}
else{
return pa;
}
}
else{
k = lenB – lenA;
while(k){
pb = pb->next;
k–;
}
while(pa && pb && pa != pb){
pa = pa->next;
pb = pb->next;
}
if(pa nullptr){
return nullptr;
}
else{
return pa;
}
}
}
过
“`cpp
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
if(headA == nullptr || headB == nullptr){
return nullptr;
}
ListNode* l1 = headA;
ListNode* l2 = headB;
int len1 = 1;
while(l1->next != nullptr){
len1++;
l1 = l1->next;
}
int len2 = 1;
while(l2->next != nullptr){
len2++;
l2 = l2->next;
}
if(l1 != l2){
return nullptr;
}
int len = len1 – len2;
if(len > 0){
while(len–){
headA = headA->next;
}
}else{
while(len++ != 0){
headB = headB->next;
}
}
while(headA != headB){
headA = headA->next;
headB = headB->next;
}
return headA;
}
};
本题是主要是双指针遍历过程中,如何使用差值,
比较巧妙的是先获取差值,
然后根据差值让双链表处于同一个起点,
并判断何时相交
#python解题
class Solution(object):
def getIntersectionNode(self, headA, headB):
“””
:type head1, head1: ListNode
:rtype: ListNode
“””
if headA is None or headB is None:
return None
//c 找公共点,1看是否为空,两值是否相等,不等的话,不为空各自下移,如果为空就等于另一个链表,然后满足相等跳出循环;
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode next;
* };
*/
struct ListNode *getIntersectionNode(struct ListNode *headA, struct ListNode *headB) {
struct ListNode *amd=headA;
struct ListNode *inter=headB;
if(!headA||!headB)
return NULL;
/while (pA != pB) {
pA = pA NULL ? headB : pA->next;
pB = pB NULL ? headA : pB->next;
}*/
while(amd!=inter){
if(amdNULL){
amd=headB;
}else{
amd=amd->next;
}
return amd;
}
思路:循环遍历两列表找到公共值
时间复杂度O(n^2),空间复杂度O(1)
/**
*打卡
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) {
* val = x;
* next = null;
* }
* }
*/
class Solution {
ListNode getIntersectionNode(ListNode headA, ListNode headB) {
if(headA null || headB null)
return null;
}
時間複雜度 O(M+N) 空間複雜度 O(1)
具體思路:
因為可能兩條長度不一樣, 我們可以利用一個技巧, 同時從第一條跟第二條起點開始遍歷,
如果到盡頭了則回到另一條的起點, 再繼續往前遍歷, 如果有交點的話, 則兩個遍歷元素會剛好相遇
沒有交點則兩個遍歷元素會在尾端NULL相遇
时间复杂度:O(M+N), 空间复杂度:O(1)
妙啊,个人理解是把两个链表连接成8的形状,上下两个圈代表两个链表,中间的交点是两个链表重合部分
以例1为例
时间O m+n
空间O 1
程序员的浪漫?走完自己路走你来时的路
class Solution {
ListNode getIntersectionNode(ListNode headA, ListNode headB) {
ListNode p = headA;
ListNode q = headB;
}
时间复杂度 O(M+N)
空间复杂度 O(1)
“`python
这辈子想不到还能这样
class Solution:
def getIntersectionNode(self, headA: ListNode, headB: ListNode) -> ListNode:
if not headA or not headB:
return None
打卡
两个指针分别遍历两个链表,当走到链表尾后从另一个链表头开始走,最终两个指针会在第一个公共点相遇或者在链表尾后面(null)相遇
时间复杂度O(m+n),空间复杂度O(10);
“`C++
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
if (headA == nullptr || headB == nullptr) {
return nullptr;
}
auto *p = headA;
auto *q = headB;
while (p != q) {
p = p == nullptr ? headB : p->next;
q = q == nullptr ? headA : q->next;
}
return p;
}
};
“`
打卡
双指针思路,核心点在于让俩指针对齐,不过我写的比较啰嗦。。
时间复杂度:O(m+n)空间复杂度O(1)
时间复杂度O(m+n) 空间复杂度O(1)
1、双指针迭代或HashSet
2、时间复杂度O(n+m),空间复杂度O(1)
时间复杂度O(n) 空间复杂度O(1)
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
if (!headA || !headB) return NULL; //有一个为空 完全不成立
};
时间O(n+m) 空间O(1)