”’python
def getIntersectionNode(self, headA, headB):
“””
:type head1, head1: ListNode
:rtype: ListNode
“””
if not headA or not headB:
return None
pa = headA
pb = headB
while pa != pb:
pa = headB if pa is None else pa.next
pb = headA if pb is None else pb.next
# 如果两个链表没有交点,最终会同时到达尾部,此时 pa 和 pb 都为 None,返回 None
if pa == None and pb == None:
return None
return pa # 返回交点或者 None
时间复杂度:O(n+m),n 和 m 表示两个链表长度
空间复杂度:O(1)
class Solution:
def getIntersectionNode(self, headA: ListNode, headB: ListNode) -> ListNode:
if headA is None and headB is None:
return None
pa = headA
pb = headB
while pa != pb:
if pa:
pa = pa.next
else:
pa = headB
if pb:
pb = pb.next
else:
pb = headA
return pa
# 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
"""
a = headA
b = headB
while a!=b:
if a:
a = a.next
else:
a = headB
if b:
b = b.next
else:
b = headA
return b
”’python
class Solution:
def getIntersectionNode(self, headA: ListNode, headB: ListNode) -> ListNode:
A, B = headA, headB
while A != B:
A = A.next if A else headB
B = B.next if B else headA
return A
时间复杂度:O(m+n) 空间复杂度:O(1)
class Solution {
ListNode getIntersectionNode(ListNode headA, ListNode headB) {
if (headA null || headB null) {
return null;
}
ListNode A = headA;
ListNode B = headB;
while (A != B) {
A = A null ? headB : A.next;
B = B null ? headA : B.next;
}
return A;
}
}
时间复杂复:O(m+n) m和n为两个链表的长度
/**
* @param {ListNode} headA
* @param {ListNode} headB
* @return {ListNode}
*/
var getIntersectionNode = function (headA, headB) {
let lA = 0, lB = 0, step = 0;
let nA = headA;
let nB = headB;
if(!nA || !nB) return null;
while (nA.next) {
lA++;
nA = nA.next;
}
while (nB.next) {
lB++;
nB = nB.next;
}
nA = headA;
nB = headB;
if (lA > lB) {
step = lA – lB;
for (let i = 0; i < step; i++) {
nA = nA.next;
}
} else if (lA < lB) {
step = lB – lA;
for (let i = 0; i < step; i++) {
nB = nB.next;
}
}
while (nA && nB) {
if (nA.val nB.val) return nA;
nA = nA.next;
nB = nB.next;
}
return null;
};
代码:public 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;
}
}
class Solution {
ListNode getIntersectionNode(ListNode headA, ListNode headB) {
// 定义两个引用链表
ListNode A = headA , B = headB;
while (A != B) {
// A与B同时走,肯定会重合,如果重合的时为空,则无相交点,如果不为空则此值为重合的链表
A = A != null ? A.next : headB;
B = B != null ? B.next : headA;
}
return A;
}
}
//空间复杂度 O(1)时间复杂度 O(n)
public class Solution {
public ListNode FindFirstCommonNode(ListNode pHead1, ListNode pHead2) {
if (pHead1 == null || pHead2 == null) {
return null;
}
ListNode A = pHead1;
ListNode B = pHead2;
while (A != B) {
A = A == null ? pHead2 : A.next;
B = B == null ? pHead1 : B.next;
}
return A;
}
}
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution:
def getIntersectionNode(self, headA: ListNode, headB: ListNode) -> ListNode:
if not headA or not headB:
return None
A = headA
B = 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 headA is None or headB is None:
return None
ha, hb = headA, headB
while ha != hb:
if ha:
ha = ha.next
else:
ha = headB
if hb:
hb = hb.next
else:
hb = headA
return ha
“`java
class Solution {
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;
}
}
“`java
时间复杂度O(M + N), 空间复杂度O(1)
class Solution:
def trainingPlan(self, head: Optional[ListNode], cnt: int) -> Optional[ListNode]:
count = 0
fast = head
slow = head
while count != cnt:
fast = fast.next
count +=1
while fast != None:
fast = fast.next
slow = slow.next
return slow
共以下 77 个回答
两个指针往前遍历
A走到null 指向B,继续走B的路
B走到null 指向A,继续走A的路
两个指针会相交,这就是他们的公共节点
”’python
def getIntersectionNode(self, headA, headB):
“””
:type head1, head1: ListNode
:rtype: ListNode
“””
if not headA or not headB:
return None
时间复杂度为 O(m+n);空间复杂度O(1)
“`c++
class Solution {
public:
ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
ListNode *curA = headA;
ListNode *curB = headB;
int lensA = 0, lensB = 0;
while(curA != nullptr) {
lensA++;
curA = curA->next;
}
};
“`
时间复杂度:O(n + m)
空间复杂度:O(1)
时间复杂度:O(n+m),n 和 m 表示两个链表长度
空间复杂度:O(1)
class Solution:
def getIntersectionNode(self, headA: ListNode, headB: ListNode) -> ListNode:
if headA is None and headB is None:
return None
pa = headA
pb = headB
while pa != pb:
if pa:
pa = pa.next
else:
pa = headB
if pb:
pb = pb.next
else:
pb = headA
return pa
// 使用交替遍历
class Solution {
ListNode getIntersectionNode(ListNode headA, ListNode headB) {
if (headA null && headB null) {
return headA;
}
}
//求两个链表的第一个交点,思路:双指针,长链表指针先移动使其剩余元素个数与短链表长度一致。然后双指针一起移动,找地址相同处
class Solution {
public:
ListNode getIntersectionNode(ListNode *headA, ListNode *headB) {
ListNode curA = headA;
ListNode* curB = headB;
int lenA = 0;
int lenB = 0;
while(curA != NULL)
{
lenA++;
curA = curA->next;
}
while(curB != NULL)
{
lenB++;
curB = curB->next;
}
curA = headA;
curB = headB;
if(lenB > lenA)
{
swap(lenA,lenB);
swap(curA,curB);
}
int gap = lenA-lenB;
while(gap–)
{
curA = curA->next;
}
while(curA != NULL){
if(curA curB)
{return curA;}
curA = curA->next;
curB = curB->next;
};
第四次打卡
”’python
class Solution:
def getIntersectionNode(self, headA: ListNode, headB: ListNode) -> ListNode:
A, B = headA, headB
while A != B:
A = A.next if A else headB
B = B.next if B else headA
return A
时间复杂度: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) {
ListNode l1 = headA;
ListNode l2 = headB;
};
当不存在交点时,NULL就被视为交点,因此判断条件不能为l1.next.
时间复杂度: O(n)
空间复杂度: O(1)
class Solution {
ListNode getIntersectionNode(ListNode headA, ListNode headB) {
if (headA null || headB null) {
return null;
}
ListNode A = headA;
ListNode B = headB;
while (A != B) {
A = A null ? headB : A.next;
B = B null ? headA : B.next;
}
return A;
}
}
时间复杂复:O(m+n) m和n为两个链表的长度
//先求出两条链表的长度之差num,再让长的链表先走num个结点,再同时向后遍历两条链表,并判断是否为同一个结点
struct ListNode *getIntersectionNode(struct ListNode *headA, struct ListNode *headB) {
typedef struct ListNode ListNode;
ListNode *p = headA;
ListNode *q = headB;
int count1=0;
int count2=0;
while(p!=NULL){
p = p->next;
count1++;
}
while(q!=NULL){
q = q->next;
count2++;
}
}
/**
* 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(headAnullptr || headBnullptr) return nullptr;
int lenA = 0, lenB = 0;
ListNode A = headA;
ListNode* B = headB;
while(A != nullptr){
lenA++;
A = A->next;
}
while(B != nullptr){
lenB++;
B = B->next;
}
A = headA;
B = headB;
int diff;
if(lenA>lenB){
diff = lenA-lenB;
while(diff–){
A = A->next;
}
}else{
diff = lenB-lenA;
while(diff–){
B = B->next;
}
}
};
先统计长度差,长的先走两者相差的步数,接着两者同时向后并判断val,若相等则返回。
时间复杂度O(m+n),空间O(1)
帅地的方法更优美
ListNode getIntersectionNode(ListNode headA, ListNode headB) {
int s1=size(headA);
int s2=size(headB);
ListNode p1=headA;
ListNode p2=headB;
if(s10||s20) return null;
int d=s1-s2;
if(d>0){
while(d– >0) p1=p1.next;
}
else if(d<0){
d=-d;
while(d– >0) p2=p2.next;
}
while(p1!=p2){
p1=p1.next;
p2=p2.next;
思路:找出两个链表的长度差 保证两个链表从同样的长度出发
时间O(n),空间O(1)
题解中有一个很6的思路是:两个指针 一个先走a 然后走b 一个先走b再走a 指针相遇就是交点
#打卡
/**
* Definition for singly-linked list.
* function ListNode(val) {
* this.val = val;
* this.next = null;
* }
*/
/**
* @param {ListNode} headA
* @param {ListNode} headB
* @return {ListNode}
*/
var getIntersectionNode = function (headA, headB) {
let lA = 0, lB = 0, step = 0;
let nA = headA;
let nB = headB;
if(!nA || !nB) return null;
while (nA.next) {
lA++;
nA = nA.next;
}
while (nB.next) {
lB++;
nB = nB.next;
}
nA = headA;
nB = headB;
if (lA > lB) {
step = lA – lB;
for (let i = 0; i < step; i++) {
nA = nA.next;
}
} else if (lA < lB) {
step = lB – lA;
for (let i = 0; i < step; i++) {
nB = nB.next;
}
}
while (nA && nB) {
if (nA.val nB.val) return nA;
nA = nA.next;
nB = nB.next;
}
return null;
};
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode next;
* };
*/
struct ListNode *getIntersectionNode(struct ListNode *headA, struct ListNode *headB) {
struct ListNode A = headA;
struct ListNode* B = headB;
while(A!=B){
A = A != NULL ? A->next : headB;
B = B != NULL ? B->next : headA;
}
return A;
}学习了双指针的方法,全部都走一遍,总会到固定的汇合点
时间:O(n)
空间:O(1)
思路:
AB同时走,A走完lengthA后,B还剩C-lengthA步。A再从B开始走,A走了C-lengthA步后,B到达A,此时AB同步。
举例:
A——3,B——4,C——1;
A走到null,B走到3.还剩1.此时A转向B。
向前一步,B走完,转向A,距离末端还剩3步,A此时走在了B1.距离末端还剩3步。此时AB同步,比较两个指针是否相同即可。
class Solution {
public:
ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
int skipA,skipB;
ListNode *A = headA, *B = headB;
while(A != B){
if(A != NULL){
A = A->next;
}else{
A = headB;
}
if(B != NULL){
B = B->next;
}else{
B = headA;
}
}
return A;
}
};
方法一:先算长度,类似倒数第k节点
class Solution {
//时间复杂度O(n),空间复杂度O(1)
ListNode getIntersectionNode(ListNode headA, ListNode headB) {
//先算两条链表的长度
int alength = getListNodeLength(headA);
int blength = getListNodeLength(headB);
//再让长的链表先走到和短链表一样长度的位置
ListNode curA = headA;
ListNode curB = headB;
int num = alength-blength;
if(num > 0) {
while(num > 0) {
curA = curA.next;
num–;
}
}else {
while(num < 0) {
curB = curB.next;
num++;
}
}
//同时走,若遇到相同的则是结果
ListNode res = null;
while(curA != null) {
if(curA curB) {
res = curA;
break;
}
curA = curA.next;
curB = curB.next;
}
return res;
}
//计算链表长度函数
int getListNodeLength(ListNode node) {
int length = 0;
ListNode cur = node;
while(cur != null) {
length++;
cur = cur.next;
}
return length;
}
}
方法二:转化成环的思路,速度一样,路程不一样相遇
class Solution {
//时间复杂度O(n),空间复杂度O(1)
ListNode getIntersectionNode(ListNode headA, ListNode headB) {
//A走完走B,B走完走A,相交
ListNode curA = headA;
ListNode curB = headB;
while(curA != curB) {
curA = curAnull?headA:curA.next;
curB = curBnull?headB:curB.next;
}
return curA;
}
}
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) {
* val = x;
* next = null;
* }
* }
*/
public class Solution {
public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
int count = 0;
ListNode bighead = headA;
ListNode smhead = headB;
while (bighead!=null){
bighead = bighead.next;
count++;
}
while (smhead!=null){
smhead = smhead.next;
count–;
}
if (count > 0){
bighead = headA;
smhead = headB;
}else {
bighead = headB;
smhead = headA;
}
int aa = Math.abs(count);
while (aa>0){
bighead = bighead.next;
aa–;
}
while (bighead != null){
if (bigheadsmhead){
return bighead;
}
bighead = bighead.next;
smhead = smhead.next;
}
return null;
}
}
//先让链表长度长的先走m-n步
/**
* 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;
ListNode p1 = headA;
ListNode p2 = headB;
}
时间复杂度o(n+m),空间复杂度O(1)。
时间复杂度为O(m+n)即链表长度之和,空间复杂度为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 * A = headA;
ListNode *B = headB;
while(A!=B)
{
A= Anullptr?headB:A->next;
B = Bnullptr?headA:B->next;
}
return A;
};
同时遍历A和B,长度分别为a和b,A与B的相同节点长度为c,遍历结束后转为遍历另一链表,当访问至相同节点后输出。
时间复杂度为O(M+N),空间复杂度为O(1)
时间复杂度:O(n+m)
空间复杂度:O(1)
java
class Solution {
ListNode getIntersectionNode(ListNode headA, ListNode headB) {
}
提交
提交/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) {
* val = x;
* next = null;
* }
* }
*/
public class Solution {
public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
ListNode d1 = headA;
ListNode d2 = headB;
if (d1null||d2null) return null;
while (d1!=d2)
{
if (d1!=null)
{
d1 =d1.next;
}
代码:public 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;
}
}
class Solution {
ListNode getIntersectionNode(ListNode headA, ListNode headB) {
ListNode temp1=headA;
ListNode temp2=headB;
while((temp1!=null)||(temp2!=null))
{
if(temp1temp2)
return temp1;
if(temp1null)
temp1=headB;
else
temp1=temp1.next;
if(temp2null)
temp2=headA;
else
temp2=temp2.next;
}
return null;
}
}
两个变量分别从两个链表的起点进行第一次遍历,任何一方走到了null,就立刻换到另一个链表的起点进行第二次遍历,由于总的路程(两次遍历)是相同的,那么在这过程中碰到相同的节点就是相交节点,如果两次遍历都走完了还是没有找到相同的节点,那么就说明没有公共节点。
最差情况时间复杂度O(A+B)
空间复杂度O(1)
思路:参考题解,属实没搞懂题意,这skip值不就用不到???
代码:
“`java
ListNode getIntersectionNode(ListNode headA, ListNode headB) {
if (null == headA || null == headB) {
return null;
}
ListNode n1 = headA;
ListNode n2 = headB;
while (n1 != n2) {
n1 = n1 == null ? headB : n1.next;
n2 = n2 == null ? headA : n2.next;
}
return n1;
}
时间复杂度O(N)
空间复杂度O(1)
最差情况时间复杂度O(A+B)
空间复杂度O(1)
最差情况时间复杂度O(A+B)
空间复杂度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) {
//分别定义遍历链表A和链表B的两个指针
ListNode *a=headA;
ListNode *b=headB;
while(a!=b){
//a遍历
if(a!=nullptr){
a=a->next;
}
else{
a=headB;
}
//b遍历
if(b!=nullptr){
b=b->next;
}
else{
b=headA;
}
}
//a和b相遇处即为所求
return b;
}
};
\\最差情况时间复杂度O(A+B)
\\空间复杂度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) {
ListNode a = headA;
ListNode b = headB;
while(a != b){
a = a != null ?a.next: headB;
b = b != null ?b.next: headA;
}
//两个走的步数一样多,最后如果没有相同的结点指向,最后就是共同指向null
return null;
}
只想到了最简单的思路,通过长度来确定。
最优解很巧妙。
时间复杂度最好为(A+B-C)
最差为O(A+B)
分两种情况:
1、相交
两个链表有交点时,可以分为三部分,设交点为C
a:A链表到交点的节点数(不含交点C)
b:B链表到交点的节点数(不含交点C)
c:交点C到链表结束的节点数(含交点C)
A链表长为a+c
B链表长为b+c
当headA走完A链表,headB走完B链表,两个指针走过的节点数分别是a+c,b+c
若此时headA从链表B出发,headB从链表A出发,则两个节点在走到交点C时走过的步长分别为a+c+b,b+c+a,走过的节点数相等,步长一致的情况下,则说明同时到达交点C,此时返回任意一个指针即为交点C。
2、不相交
不相交可以看做是两个链表在None节点处相交,同样两个指针在遍历完A/B链表之后遍历B/A链表,指针在None节点交汇,则链表不相交。
时间复杂度O(A+B):最差情况遍历两个链表
空间复杂度O(1):常量空间
通过总路程不变进行双向遍历
class Solution {
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 : headB;
}
return A;
}
}
本题思路是A遍历完自己的链表之后就去遍历B链表,B遍历完自己的链表后就遍历A链表,假如他们两个是相交的话,那么一定会同时遍历到那个交点
class Solution {
ListNode getIntersectionNode(ListNode headA, ListNode headB) {
if(headA null || headB null) return null;
ListNode A = headA;
ListNode B = headB;
}
这道题学408的时候遇到过,结果又忘了,用了地哥的解法,真的优雅
时间复杂度O(m+n)空间复杂度O(1)
public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
int lenA = 0, lenB = 0;
ListNode nodeA = headA, nodeB = headB;
while(nodeA!=null){
lenA++;
nodeA = nodeA.next;
}
while(nodeB!=null){
lenB++;
nodeB = nodeB.next;
}
nodeA = headA;
nodeB = headB;
if(lenB > lenA)return getIntersectionNode(headB,headA);
int distance = lenA – lenB;
for(int i = 0; i < distance; i++)nodeA = nodeA.next;//保证尾部对齐
while(nodeA != null){
if(nodeA nodeB)return nodeA;
nodeA = nodeA.next;
nodeB = nodeB.next;
}
return null;
}
时间复杂度O(n)
空间复杂度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(n)
空间复杂度O(1)
时间复杂度O(n+m),空间复杂度O(1)
class Solution {
public:
ListNode getIntersectionNode(ListNode *headA, ListNode *headB) {
int A_length=0,B_length=0;
ListNodep=headA; ListNode*q=headB;
while(p!=nullptr)
{
p=p->next;
A_length++;
}
while(q!=nullptr)
{
q=q->next;
B_length++;
}
int k=0; int AorB=1;
if(A_length>=B_length)
{ k=A_length-B_length; AorB=1; }
else { k=B_length-A_length; AorB=0; }
};
打卡
时间复杂度为(O(m+n)),空间复杂度为(O(1))。
时间o(n+m)
空间o(1)
思路
浪漫的话母胎单身直男不多说,这个解法的本质是让两个指针在会合点前走到路程相等从而会合。
复杂度
时间复杂度:
O(M+N)
class Solution {
public:
ListNode getIntersectionNode(ListNode *headA, ListNode *headB) {
ListNodepA=headA;
ListNode*pB=headB;
int lenA=0;
int lenB=0;
};
时间复杂度:O(M+N)
空间复杂度:O(1)
时间复杂度O(N)空间复杂度O(1)
时间复杂度:o(n+m) 空间复杂度o(n)
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
struct ListNode *getIntersectionNode(struct ListNode *headA, struct ListNode *headB) {
struct ListNode *n1 = headA;
struct ListNode *n2 = headB;
if(n1 NULL || n2 NULL){return NULL;}
}
时间复杂度:O(N+M);空间复杂度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) {
ListNode curA = headA;
ListNode* curB = headB;
int a=0, b=0;
while(curA){
a++;
curA = curA->next;
}
while(curB){
b++;
curB = curB->next;
}
curA = headA, curB = headB;
if(a<b) swap(curA, curB);
for(int i=0; i<abs(a-b); i++){
curA = curA->next;
}
while(curA && curB){
if(curA->val curB->val) break;
curA = curA->next;
curB = curB->next;
}
return curA;
}
};
时间复杂O(A+B)空间复杂O(1)
class Solution {
ListNode getIntersectionNode(ListNode headA, ListNode headB) {
if(headA null || headB null){
return null;
}
ListNode A = headA;
ListNode B = headB;
while(A != B){
A = A != null ? A.next : headB;
B = B != null ? B.next : headA;
}
return A;
}
}时间复杂O(A+B)空间复杂O(1)
“`C++
//思路:双指针,ab同时遍历,然后去遍历对方,若相等,说明相遇
/**
* 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 *A, *B;
A = headA, B = headB;
if(A NULL || B NULL) return NULL;
while(A != B){
A = A NULL ? headB : A->next;
B = B NULL ? headA : B->next;
}
return A;
}
};
“`
时间复杂度
O(n)
空间复杂度
O(1)
“`java
class Solution {
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;
}
}
“`java
时间复杂度O(M + N), 空间复杂度O(1)
时间复杂度O(n)
空间复杂度O(1)
Definition for singly-linked list.
class ListNode:
def init(self, val=0, next=None):
self.val = val
self.next = next
class Solution:
def trainingPlan(self, head: Optional[ListNode], cnt: int) -> Optional[ListNode]:
count = 0
fast = head
slow = head
while count != cnt:
fast = fast.next
count +=1
依旧很直接的解法,制造步数差然后遍历到尾部。记住返回节点而不是val。
时间o(N)无循环,空间o(1)常数空间
时间复杂度 O(n),空间复杂度 O(1)
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) {
* val = x;
* next = null;
* }
* }
*/
class Solution {
/**
* 扫描三次链表,时间复杂度为O(n),空间复杂度固定了几个O(1)
*/
ListNode getIntersectionNode(ListNode headA, ListNode headB) {
if(headA null || headB null){
return null;
}
int lenA = 0;
int lenB = 0;
ListNode tempA = headA;
ListNode tempB = headB;
//先遍历两次链表,分别得到链表的长度
while(tempA != null){
tempA = tempA.next;
++ lenA;
}
while(tempB != null){
tempB = tempB.next;
++ lenB;
}
//假如B链表长度大指针改一下减少下面代码重复性
if(lenB > lenA){
int tempLen = lenA;
lenA = lenB;
lenB = tempLen;
ListNode tempNode = headA;
headA = headB;
headB = tempNode;
}
//注意=
if(lenA >= lenB){
tempA = headA;
for(int i = 0; i < lenA – lenB; i ++){
tempA = tempA.next;
}
tempB = headB;
while(tempA != tempB){
tempA = tempA.next;
tempB = tempB.next;
}
return tempA;
}
return null;
}
}
两个链表的第一个公共节点java
/**
* 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) {
// a长度为n,b长度为m,双指针同时走到尾,若为空返回到对方的头指针。
// 此时,若双方再相遇,则找到公共节点。
ListNode a = headA;
ListNode* b = headB;
while(a != b){ // 若ab同时为空,则公共节点为空
a = a ? a->next : headB;
b = b ? b->next : headA;
}
return a;
}
};
时间复杂度O(n+m),空间复杂度O(1)
“`C++
class Solution {
public:
ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
ListNode *A = headA, *B = headB;
while(A != B)
{
A = A != nullptr? A->next : headB;
B = B != nullptr? B->next : headA;
}
return A;
}
};
方法:双指针
时间复杂度:o(n)
空间复杂度:o(1)
如有问题,欢迎指正!
时间复杂度:O(n)
空间复杂度:O(1)
思路:分别计算出两个链表的长度,长的那个链表的头节点先前进长度差值diff步,然后两个链表一起前进,当遇到相同的节点时,则为两个链表的第一个相同节点。
“`C++
class Solution {
public:
ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
int lenA=0, lenB=0;
ListNode *curA = headA;
while (curA != nullptr) {
lenA++;
curA = curA->next;
}
ListNode *curB = headB;
while (curB != nullptr) {
lenB++;
curB = curB->next;
}
if (lenA < lenB) { curA = headA; headA = headB; headB = curA; int temp = lenA; lenA = lenB; lenB = temp; } int diff = lenA - lenB; while (diff > 0) {
diff–;
headA = headA->next;
}
while (headA && headB) {
if (headA->val == headB->val) break;
headA = headA->next;
headB = headB->next;
}
return headA;
}
};
“`
“`java
class Solution {
ListNode getIntersectionNode(ListNode headA, ListNode headB) {
ListNode tempB = headB;
while(headA!=null){
while(tempB!=null){
if(headA==tempB){
return headA;
}
tempB = tempB.next;
}
tempB = headB;
headA = headA.next;
}
return null;
}
}
时间复杂度:O(n2),直接暴力法做出来的,效率很差,没想到先算下两个长度然后遍历,看了其他学员的思路才知道了。
方法1:计算两个链表长度差值diff,让长链表先走diff,然后两个链表一起走,走到相同位置时返回此位置的节点
方法2:走总路程,A走完了自己的路开始走B的路,B走完了自己的路开始走A的路。因为总路程是一样的,多走的路对方也要走,就总会走到同一起点。
时间复杂度o(n)
空间复杂度o(1)
###C++
”’
class Solution {
public:
ListNode* trainingPlan(ListNode* head, int cnt) {
if ( head nullptr )
{
return nullptr;
}
};
”’
class Solution {
ListNode getIntersectionNode(ListNode headA, ListNode headB) {
if(headA null || headB null)
return null;
ListNode ptrA = headA;
int lenA = 0;
ListNode ptrB = headB;
int lenB = 0;
while(ptrA.next!=null){
lenA++;
ptrA = ptrA.next;
}
}
两次遍历,第一次获得两条链表长度。第二次长链表指针先走长度之差步。
时间复杂度On
空间复杂度 O1
时间复杂度:O(n)
空间复杂度:O(1)
双指针,day1打卡完毕
/**
* 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;
// 寻找公共节点
ListNode nodeA = headA;
ListNode nodeB = headB;
int numA = 0;
int numB = 0;
while(nodeA.next != null){
nodeA = nodeA.next;
numA ++;
}
while(nodeB.next != null){
nodeB = nodeB.next;
numB ++;
}
if(nodeA != nodeB){
return null;
}
}
快慢指针
day1 打卡完毕,感觉还可以
我吹过你吹过的晚风,那我们算不算相拥?