# 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
"""
if not headA and not headB:
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 headA is None or headB is None:
return None
else:
pA = headA
pB = headB
while (pA != pB):
if pA.next is None and pB.next is None:
return None
if pA.next is None:
pA = headB
else:
pA = pA.next
if pB.next is None:
pB = headA
else:
pB = pB.next
return pA
打卡
class Solution {
public:
ListNode getIntersectionNode(ListNode *headA, ListNode *headB) {
int al = 0,bl = 0;
ListNode na = headA, *nb = headB;
while(na){
al++;
na = na ->next;
}
while(nb){
bl++;
nb = nb ->next;
}
na = headA;
nb = headB;
if(al > bl){
for(;al>bl;al–){
na = na->next;
}
}else{
for(;bl>al;bl–){
nb = nb->next;
}
}
while(na && nb && na != nb){
na = na->next;
nb = nb->next;
}
if (nb != nullptr){
return nb;
}
else
return nullptr;
}
};
打卡
class Solution {
ListNode getIntersectionNode(ListNode headA, ListNode headB) {
ListNode a = headA, b = headB;
if(a null || b null){
return null;
}
while (a != b){
a = a null ? headA : a.next;
b = b null ? headB : b.next;
}
return a;
}
}
代码实现:
class ListNode:
def init(self, x=None):
self.data = x
self.next = None
class Solution(ListNode):
def IntersectionNode(self, headA, headB):
hash_lis = []
cur = headA
while cur!= None:
hash_lis.insert(cur)
cur = cur.next
cur = headB
while cur!=None:
if cur in hash_lis:
return cur
cur = cur.next
return None
// C++实现
class Solution {
public:
ListNode getIntersectionNode(ListNode *headA, ListNode *headB) {
if (!headA || !headB) {
return nullptr;
}
ListNode A = headA;
ListNode* B = headB;
while (A != B) {
A = A ? A->next : headB;
B = B ? B->next : headA;
}
return A;
}
};
public class 两个链表的第一个公共节点 {
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;
}
return A;
}
}
“`/**
* Definition for singly-linked list.
* type ListNode struct {
* Val int
* Next *ListNode
* }
*/
func getIntersectionNode(headA, headB *ListNode) *ListNode {
a := headA
b := headB
for a != b{
if a == nil{
a = headB
}else {
a = a.Next
}
if b == nil{
b = headA
}else{
b = b.Next
}
}
return a
class Solution:
def getKthFromEnd(self, head: ListNode, k: int) -> ListNode:
pre = head
cur = pre
for i in range(k):
cur = cur.next
while cur:
pre = pre.next
cur = cur.next
return pre
共以下 68 个回答
两个链表第一个公共节点,java。思路很重要,因为A+B的长度是固定的,所以循环后有可能达到重合节点,也有可能是null
”Java
/**
* 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;}
}
【两个链表的第一个公共节点】C++
打卡
思路:假定共同尾部分为C,前面分别为A,B。A+C+B = B+C+A, 此时双指针到达同一节点
注意:链表A走到尾换链表B走时,已经节点前进了,因此不能再按.next来,所以这里应该是选择条件
时间复杂度:O(N+M)
空间复杂度:O(1)
打卡
双指针可以走的步长不同,也可以相同,找相同节点可以循环。走完A走B,到相同节点的步数是一致的。如果没有公共节点,最后都指向null
java
/**
* 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){
if(Anull){
A=headB;
}else{
A=A.next;
}
如果有公共节点,链表A+链表B非公共部分 长度=链表B+链表A非公共部分 长度,指针A到末尾时指向链表B的头,指针B到末尾时指向链表A的头,指针A和B会在公共节点处重合。如果没有公共节点,指针A和B会同时指向Null
空间O(1)
时间O(n)
打卡
class Solution {
public:
ListNode getIntersectionNode(ListNode *headA, ListNode *headB) {
int al = 0,bl = 0;
ListNode na = headA, *nb = headB;
while(na){
al++;
na = na ->next;
}
while(nb){
bl++;
nb = nb ->next;
}
na = headA;
nb = headB;
if(al > bl){
for(;al>bl;al–){
na = na->next;
}
}else{
for(;bl>al;bl–){
nb = nb->next;
}
}
while(na && nb && na != nb){
na = na->next;
nb = nb->next;
}
if (nb != nullptr){
return nb;
}
else
return nullptr;
}
};
时间复杂度O(n)空间复杂度O(1)ListNode getIntersectionNode(ListNode headA, ListNode headB) {
//拉齐长度,再判断
int l1num=0;
int l2num=0;
ListNode l1=headA;
ListNode l2=headB;
while(l1!=null)
{
l1num++;
l1=l1.next;
}
while(l2!=null)
{
l2num++;
l2=l2.next;
}
l1=headA;
l2=headB;
while(l1num>l2num&&l1!=null)
{
l1=l1.next;
l1num–;
}
}
打卡
class Solution {
ListNode getIntersectionNode(ListNode headA, ListNode headB) {
ListNode a = headA, b = headB;
if(a null || b null){
return null;
}
while (a != b){
a = a null ? headA : a.next;
b = b null ? headB : b.next;
}
return a;
}
}
代码实现:
class ListNode:
def init(self, x=None):
self.data = x
self.next = None
class Solution(ListNode):
时间复杂度:O(n+m)
空间复杂度:O(1)
class Solution:
def getIntersectionNode(self, headA: ListNode, headB: ListNode) -> ListNode:
A,B=0,0
cur1 = headA
cur2 = headB
while cur1:
cur1=cur1.next
A+=1
while cur2:
cur2=cur2.next
B+=1
cur1,cur2=headA,headB
if A>B:
for _ in range(A-B):
cur1=cur1.next
if B>A:
for _ in range(B-A):
cur2=cur2.next
while cur1:
if cur1 cur2:
return cur1
else:
cur1 = cur1.next
cur2 = cur2.next
return None
计算长度,从公共剩余长度开始比较
参考的题解,自己没想出来。双指针
2.时间复杂度O(N) 空间复杂度O(1)
class Solution {
ListNode getIntersectionNode(ListNode headA, ListNode headB) {
if(headAnull || headB null)return null;
ListNode cur1=headA;
ListNode cur2=headB;
while(cur1!=cur2){
cur1=cur1null?headB:cur1.next;//不是?cur2 ,会出现空指针,两个都指向空后报错程序结束
cur2=cur2null?headA:cur2.next;
}
return cur1;
}
}
时间复杂度O(n)
空间复杂度O(1)
同时遍历,要么在共同节点,要么同时为空
时间复杂度:O(m+n)
空间复杂度O1
class Solution {
ListNode getIntersectionNode(ListNode headA, ListNode headB) {
if(headA null || headB null) return null;
ListNode pa = headA;
ListNode pb = headB;
while (pa != pb) {
pa = pa null ? headB : pa.next;
pb = pb null ? headA : pb.next;
}
return pa;
}
}
/**
两个链表同时遍历完最终停留在共同节点或者同时为空值
* 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;
ListNode *pb = headB;
while(pa != pb){
pa = (pa != nullptr ? pa->next : headB);
pb = (pb != nullptr ? pb->next : headA);
}
return pa;
}
};
估计也就我用TS了
第一天第四题
// C++实现
class Solution {
public:
ListNode getIntersectionNode(ListNode *headA, ListNode *headB) {
if (!headA || !headB) {
return nullptr;
}
ListNode A = headA;
ListNode* B = headB;
while (A != B) {
A = A ? A->next : headB;
B = B ? B->next : headA;
}
return A;
}
};
看了视频。速度相同,路程不同,想要同时到达:要么先后出发;要么走相同长度的路。
时间复杂度:O(n)
空间复杂度:O(1)
c++ 代码 相爱的人总会相遇
class Solution {
public:
ListNode* getIntersectionNode(ListNode* headA, ListNode* headB)
{
ListNode* h1 = headA;
ListNode* h2 = headB;
while (h1 != h2)
{
h1 = h1 NULL ? headB : h1->next;
h2 = h2 NULL ? headA : h2->next;
};
写了两个解法,但其实本质是一样的,都是双指针。只是2相当于1的拆解,形象理解了过程。
解法一
用p、q两个节点来分别遍历headA和headB,在遍历的时候判断当前节点是否为空,若为空就取另一个链表的开头。就是相当于把两个链表连接,p在ABABAB···中遍历,q在BABABA···中遍历,变成了一个追及问题,他们总会遇上的。
解法二
先遍历两个链表得到长度,根据两个链表的长度差,让长的链表先走gap步,然后共同遍历,若有共同节点就输出
代码
代码如下
时间复杂度 O(n)
空间复杂度 O(1)
这题没有想出来,看完题解,理解了。我将思路拆解如下:
1. 要判断两个链表有没有相交,翻译成代码就是链表节点是否相等 -> A = B
2. 要做到这一步的关键,就得先让他们能同时走,且最后都能一起走到终点。也就是他们走的长度要一样。
3. 而原始链表长度不一定相同,我们要通过一些方法,让长的那一个链表先走几步,达到和短链表一样的步数。
4. 一种方法比较好想的是,算出两个链表的长度差值x,让长链表走x步。再通过第一点提到的条件,就能找到相交点。
5. 另一种方法,也就是下面这种比较巧一点的方法。就是通过循环走链表的形式,最终达到步数的统一。走到空时,继续从另一条链表开始走,在某一个时刻,两个指针会统一步伐。
时间复杂度:O(n)
空间复杂度:O(1)
双指针
思路
1. 设置两个指针,记为A和B,一开始A指向链表A的头节点,B指向链表B的头节点。
2. 让A和B同时向后移动,当A到达链表A的尾部时,让A重新定位到链表B的头节点;当B到达链表B的尾部时,让B重新定位到链表A的头节点。
3. 当A和B相遇时,相遇的点即为两个链表的第一个公共节点。如果没有公共节点,那么最后A和B会同时为null。
为什么这个算法可以找到第一个公共节点呢?原因在于,这个算法可以消除两个链表长度的差异。假设链表A的长度为a+c,链表B的长度为b+c,其中c为两个链表的公共部分,a为链表A的独有部分,b为链表B的独有部分。那么,按照算法,A指针实际上走过的路径为a+c+b,B指针走过的路径为b+c+a,两者相同。这意味着,如果有公共节点,A和B一定会在公共节点处相遇;如果没有公共节点,A和B一定会在两个链表末尾处相遇,此时A和B都为null。
代码
时间复杂度:O(m+n) 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(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(n+m)
//空间复杂度O(1)
双指针,时间 O(M+N), 两个链表的长度; 空间O(1)
代码
双指针两个链表的第一个公共节点。 O(m+n)
java
代码
双指针法
/**
* 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 A = headA;
ListNode B = headB;
}
—
“`/**
* Definition for singly-linked list.
* type ListNode struct {
* Val int
* Next *ListNode
* }
*/
func getIntersectionNode(headA, headB *ListNode) *ListNode {
a := headA
b := headB
for a != b{
if a == nil{
a = headB
}else {
a = a.Next
}
}
“`
打卡
一
/**
* 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 A = headA;
ListNode B = headB;
while (A != B) {
A = A null ? headB : A.next;
B = B null ? headA : B.next;
}
return A;
}
}
2.时间复杂度O(n+m),空间复杂度O(1)
时间O(n) 空间O(1)
时间复杂度:O(m+n)
空间复杂度:O(1)
代码
Day1:下面是代码
时间复杂度:O(n)
空间复杂度:O(1)
”C++
class Solution {
public:
ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
if(headANULL&&headBNULL)return NULL;
};
执行用时:40 ms
//遍历长度
class Solution {
ListNode getIntersectionNode(ListNode headA, ListNode headB) {
if(headA null || headB null) return null;
}
时间复杂度 O(N) 空间复杂度 O(1)
时间复杂度:O(M+N)
空间复杂度:O(1)
时间复杂度:O(m+n)
时间复杂度:O(m+n)
空间复杂度:O(1)
时间复杂度:O(m+n)
空间复杂度:O(max(m,n))
它说必须包含中文