Open azl397985856 opened 3 years ago
思路
代码 ‘ ListNode getIntersectionNode(ListNode headA, ListNode headB) { //上面方法超过时间限制,将上面方法改为哈希表,会减少时间消耗 //下面采用双指针方法 ListNode nodeA = headA; ListNode * nodeB = headB;
if(headA==NULL||headB==NULL) return NULL;
while(1)
{
if(nodeA==nodeB) return nodeB;
if(nodeA==NULL)nodeA = headB;
else nodeA = nodeA->next;
if(nodeB==NULL)nodeB = headA;
else nodeB = nodeB->next;
}
}’
复杂度分析 时间复杂度:O(m+n) 空间复杂度:O(1)
C++ Code:
/**
* 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 lenA = getLen(headA);
auto lenB = getLen(headB);
auto diff = abs(lenA - lenB);
if (lenA > lenB) {
while (diff--) {
headA = headA->next;
}
} else {
while (diff--) {
headB = headB->next;
}
}
while (headA != nullptr && headB != nullptr) {
if (headA == headB) {
return headA;
}
headA = headA->next;
headB = headB->next;
}
return nullptr;
}
int getLen(ListNode* head) {
int res = 0;
while (head != nullptr) {
++res;
head = head->next;
}
return res;
}
};
令 n 为链表长度。
/**
} */ public class Solution { public ListNode getIntersectionNode(ListNode headA, ListNode headB) { ListNode curA = headA, curB = headB; while(curA !=curB ){ if(curA == null) { curA = headB; } else { curA = curA.next;
}
if(curB == null) {
curB = headA;
} else {
curB = curB.next;
}
}
return curA;
} }
https://leetcode.com/problems/intersection-of-two-linked-lists/
const getIntersectionNode = function(headA, headB) {
if (!headA || !headB) return null;
var curA = headA;
var curB = headB;
while (curA != curB) {
curA = curA == null ? headB : curA.next;
curB = curB == null ? headA : curB.next;
}
return curA;
};
};
时间 O(m+n) 空间 O(m+n)
/**
* Definition for singly-linked list.
* type ListNode struct {
* Val int
* Next *ListNode
* }
*/
func getIntersectionNode(headA, headB *ListNode) *ListNode {
if headA == nil || headB ==nil {
return nil
}
pa, pb := headA, headB
count := 0
for pa != pb {
if pa == nil {
pa = headB
count++
} else {
pa = pa.Next
}
if pb == nil {
pb = headA
count++
} else {
pb = pb.Next
}
if count > 2 {
return nil
}
}
return pa
}
采用set来实现,先遍历一遍A,在遍历B,如果遍历B时,节点存在 则返回;该解法为简单题;
public class Solution {
public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
Set<ListNode> set = new HashSet<>();
while(headA != null){
set.add(headA);
headA = headA.next;
}
ListNode cur = headB;
while(cur != null){
if(set.contains(cur)){
return cur;
}
cur = cur.next;
}
return null;
}
}
其中 m 和 n 是分别是链表 headA 和 headB 的长度
时间复杂度:O(m+n) 都要遍历A和B
空间复杂度:o(m) 要保存A中的节点信息
相向运动相遇问题 先计算长度,得出长短链表的差值diff
,让长链表先走diff
个距离,然后让长短链表以同速向前走,直到两指针相撞(有交点)或者两指针都走到了末尾(==null
)代表没有交点
var getIntersectionNode = function(headA, headB) {
if (!headA || !headB) return null;
let p1 = headA , p2 = headB;
// 先计算长度
let len1 = 0 , len2 = 0;
while(p1) {
p1 = p1.next;
len1++;
}
while(p2) {
p2 = p2.next;
len2++;
}
let fast , slow;
let diff = Math.abs(len1 - len2);
if (len1 > len2) {
fast = headA; slow = headB;
} else {
fast = headB; slow = headA;
}
while(diff){
--diff;
fast = fast.next;
}
while(fast && slow && fast !== slow) {
fast = fast.next;
slow = slow.next;
}
return slow;
};
时间复杂度:o(n)
一趟计算长度,一趟双指针走一趟
额外空间复杂度: o(1)
链表
, 双指针
先算出链表A与链表B的length
,然后算出两者之间的差值diffrence
,让两者中最长的的链表先走diffrence
步,再让较短的链表与长链表一起遍历,如果两个链表结点相同则说明两个链表相交了。
public class Solution {
public int getLen(ListNode head){
ListNode temp = head;
int index = 0;
while(temp != null){
index++;
temp = temp.next;
}
return index;
}
public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
int a = getLen(headA);
int b = getLen(headB);
int difference = Math.abs(a - b);
ListNode ta = headA;
ListNode tb = headB;
if(b > a){
for(int i = 0; i < difference ;i ++){
tb = tb.next;
}
while(tb != null){
if(tb == ta) return tb;
tb = tb.next;
ta = ta.next;
}
}else {
for(int i = 0; i < difference ;i++){
ta = ta.next;
}
while(ta != null){
if(ta == tb) return ta;
ta = ta.next;
tb = tb.next;
}
}
return null;
}
}
时间复杂度:O(n)
空间复杂度:O(1)
分别遍历两个链表获取长度,移动标记在长链表的指针,使其到长链表末尾的长度和短链表整体长度一致,两个指针分别遍历两个链表,两个指针指向的ListNode相同时,return 该ListNode
public class Solution {
public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
int lengthA = getLength(headA);
int lengthB = getLength(headB);
ListNode curA = headA;
ListNode curB = headB;
while (lengthA > lengthB && curA != null) {
lengthA--;
curA = curA.next;
}
while (lengthB > lengthA && curB != null) {
lengthB--;
curB = curB.next;
}
while(curA != null && curB != null) {
if (curA == curB) {
return curA;
}
curA = curA.next;
curB = curB.next;
}
return null;
}
public int getLength(ListNode head) {
if (head == null) {
return 0;
}
int length = 1;
ListNode cur = head;
while(cur.next != null) {
length++;
cur = cur.next;
}
return length;
}
}
时间: O(m+n) \ 空间: O(1)
双指针
class Solution {
public:
ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
ListNode* a=headA,*b=headB;
while(a!=b)
{
a=a->next;
b=b->next;
if(!a&&!b)
return nullptr;
if(!a)
a=headB;
if(!b)
b=headA;
}
return a;
}
};
复杂度分析
class Solution:
def getIntersectionNode(self, headA: ListNode, headB: ListNode) -> ListNode:
cur1 = headA
cur2 = headB
while cur1 != cur2:
cur1 = cur1.next if cur1 else headB
cur2 = cur2.next if cur2 else headA
return cur1
Time: O(a+b) where a is length of list A and b is length of list B
Space: O(1)
----A----
----C----
------B----
A + C + B == B + C + A
/**
* @param {ListNode} headA
* @param {ListNode} headB
* @return {ListNode}
*/
const getIntersectionNode = function(headA, headB) {
if (!headA || !headB) return null;
let a = headA;
let b = headB;
while (a !== b) {
a = a === null ? headB : a.next;
b = b === null ? headA : b.next;
}
return a;
};
var getIntersectionNode = function(headA, headB) {
let p1 = headA;
let p2 = headB;
while (p1 !== p2) {
p1 = p1 ? p1.next : headB;
p2 = p2 ? p2.next : headA;
}
return p1;
};
public ListNode getIntersectionNode(ListNode headA, ListNode headB) { int lenA = length(headA); int lenB = length(headB); while (lenA > lenB) { headA = headA.next; lenA--; } while (lenB > lenA) { headB = headB.next; lenB--; } while (headA != headB) { headA = headA.next; headB = headB.next; } return headA; }
private int length(ListNode head) {
int len = 0;
while (head != null) {
head = head.next;
len++;
}
return len;
}
参考题解
class Solution:
def getIntersectionNode(self, headA: ListNode, headB: ListNode) -> ListNode:
A = headA
B = headB
while A != B:
A = A.next if A else headB
B = B.next if B else headA
return A
时间复杂度 O(a+b) 空间复杂度 O(1)
遍历链表A, 将所有节点加入 set
遍历链表B, 如果节点在 set 中, 那么就是相交的节点, 返回这个节点
否则就返回 None, 代表没有相交的节点
# 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:
d = set()
while headA:
d.add(headA)
headA = headA.next
while headB:
if headB in d:
return headB
headB = headB.next
return None
空间复杂度: O(m+n) m 是链表 A 的长度, n 是链表 B 的长度, 因为最坏遍历两个链表各一次
时间复杂度: O(m+n) m 是链表 A 的长度, n 是链表 B 的长度, 因为最坏可能遍历两个链表的所有元素
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) {
ListNode* p1 = headA;
ListNode* p2 = headB;
while (p1 != p2) {
p1 = p1 ? p1->next : headB;
p2 = p2 ? p2->next : headA;
}
return p1;
}
};
讲义(基础篇) -> 链表
var getIntersectionNode = function(headA, headB) {
var a = headA, b = headB;
while (a != b) {
a = a ? a.next : null;
b = b ? b.next : null;
if (a == null && b == null) return null;
if (a == null) a = headB;
if (b == null) b = headA;
}
return a;
};
时间:O(n) 空间:O(1)
a+b与b+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:
t1=headA
t2=headB
while t1 != t2:
t1=t1.next if t1 else headB
t2=t2.next if t2 else headA
return t1
Go Code:
/**
* Definition for singly-linked list.
* type ListNode struct {
* Val int
* Next *ListNode
* }
*/
func getIntersectionNode(headA, headB *ListNode) *ListNode {
nHeadA,nHeadB := headA, headB
for nHeadA != nHeadB {
nHeadA = nHeadA.Next
nHeadB = nHeadB.Next
if nHeadA == nil && nHeadB == nil {
return nil
}
if nHeadA == nil {
nHeadA = headB
}
if nHeadB == nil {
nHeadB = headA
}
}
return nHeadA
}
复杂度分析
令 n 为数组长度。
straightforward way is to use a set to record, when we find the first node we can't add to set, it is the start node of the intersection part
public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
if (headA == null || headB == null) return null;
Set<ListNode> visited = new HashSet<>();
while (headA != null || headB != null) {
if (headA != null && !visited.add(headA)) return headA;
if (headB != null && !visited.add(headB)) return headB;
headA = headA == null ? headA : headA.next;
headB = headB == null ? headB : headB.next;
}
return null;
}
time : O(m + n) space : strictly the same as time O(m + n) m, n are the length of two lists
/**
Solution - 1:
public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
int lenA = 1;
int lenB = 1;
ListNode hA = headA;
ListNode hB = headB;
while (hA != null) {
lenA++;
hA = hA.next;
}
while (hB != null) {
lenB++;
hB = hB.next;
}
while (lenA > lenB) {
headA = headA.next;
lenA--;
}
while (lenB > lenA) {
headB = headB.next;
lenB--;
}
while (headA != null && headB != null) {
if (headA == headB) {
return headA;
}
headA = headA.next;
headB = headB.next;
}
return null;
}
Solution - 2
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)
空间:O(1)
双指针,链表A或B同时开始遍历,遍历到最后一个节点后分别指向对方的头节点进行第二次遍历,这样如果相交就会在相交节点两指针相遇,返回即可;不相交就会第二次触底,这时返回即可。
class Solution:
def getIntersectionNode(self, headA: ListNode, headB: ListNode) -> ListNode:
p1, p2 = headA, headB
flag1 = flag2 = 0
while p1 != p2:
p1 = p1.next
p2 = p2.next
if p1 == None:
p1 = headB
flag1 += 1
if p2 == None:
p2 = headA
flag2 += 1
if flag1 >= 2 or flag2 >= 2:
return None
return p1
时间:O(n) n为两链表长度之和 空间:O(1)
Add pathA to the tail to PathB, and add PathB to the tail of path A.
if they have intersection, the condition while(a != b)
will terminate, and the node that a is at is what we want to return.
Else a will just reach the end of the combined list, which is null, return a <-> return null.
/**
*
A: a1 → a2
↘
c1 → c2 → c3
↗
B: b1 → b2 → b3
.
begin to intersect at node c1.
A : a1 → a2 -> c1 → c2 → c3 -> b1 → b2 → b3 -> *c1*→ c2 → c3
B : b1 → b2 → b3 -> c1 → c2 → c3 -> a1 → a2 -> *c1* → c2 → c3
time : O(m + n);
space : O(1);
*/
public 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;
}
}
Time = O(m + n) : Traverse both linkedlist twice.
Space= O(1)
o(n)
class Solution(object):
def getIntersectionNode(self, headA, headB):
"""
:type head1, head1: ListNode
:rtype: ListNode
"""
dummy_a,dummy_b = ListNode(0),ListNode(0)
dummy_a.next,dummy_b.next = headA, headB
lenA,lenB = 0,0
while headA :
lenA+=1
headA = headA.next
while headB:
lenB+=1
headB = headB.next
headA , headB = dummy_a.next, dummy_b.next
while headA and headB:
if lenA == 0 or lenB == 0:
break
if lenA > lenB :
headA = headA.next
lenA-=1
elif lenA < lenB:
headB = headB.next
lenB-=1
else:
if headB == headA:
return headB
else:
headA = headA.next
headB = headB.next
lenA-=1
lenB -=1
class Solution {
public:
ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
unordered_set<ListNode *> visited;
ListNode *temp = headA;
while (temp != nullptr) {
visited.insert(temp);
temp = temp->next;
}
temp = headB;
while (temp != nullptr) {
if (visited.count(temp)) {
return temp;
}
temp = temp->next;
}
return nullptr;
}
};
只说为什么 while a != b
因为遍历到最后 一定会是None == None
情况
# 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:
a = headA
b = headB
while a != b:
if a:
a = a.next
else:
a = headB
if b:
b = b.next
else:
b = headA
# if not a or not b:
# return None
return a
Time: O(n)
# 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
dic = {}
while headA:
dic[headA] = None
headA = headA.next
while headB:
if headB in dic:
return headB
else:
headB = headB.next
# 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:
p1 = headA
p2 = headB
while p1 != p2:
if p1 is None:
p1 = headB
else:
p1 = p1.next
if p2 is None:
p2 = headA
else:
p2 = p2.next
return p1
之前碰到过一次的题目,历遍两次找到相交的点
Time O(n)
Space O(1)
Figured out the solution using hash table, get the constant space way by reading the solution. Using the same distance logic for this quesion
class Solution:
def getIntersectionNode(self, headA: ListNode, headB: ListNode) -> ListNode:
a = headA
b = headB
while(a != b):
if not a:
a = headB
else:
a = a.next
if not b:
b = headA
else:
b = b.next
return b
Space: O(1) Time: O(N)
class Solution:
def getIntersectionNode(self, headA: ListNode, headB: ListNode) -> ListNode:
# 双指针
# a = headA
# b = headB
# while a != b:
# # 注意if a not a.next, because a could handle no intersect
# a = a.next if a else headB
# b = b.next if b else headA
# return a
# 哈希表,set()形式,list会超时
s = set()
# s = []
a = headA
b = headB
while a:
s.add(a)
# s.append(a)
a = a.next
while b:
if b in s:
return b
b = b.next
return None
哈希表 - 时间复杂度:O(N), 空间复杂度O(N) 双指针 - 时间复杂度:O(N), 空间复杂度O(1)
public class Solution {
public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
ListNode A = headA;
ListNode B = headB;
while (A != B) {
A = A == null ? headB : A.next;
B = B == null ? headA : B.next;
}
return A;
}
}
var getIntersectionNode = function(headA, headB) {
let dummyA = headA
let dummyB = headB
while(dummyA !== dummyB){
dummyA = dummyA ? dummyA.next : headB
dummyB = dummyB ? dummyB.next : headA
}
return dummyB
};
时间:O(N) 空间:O(1)
If list A and list B have intersection, they would have the same tail node (And a subset list of common nodes). When list A and list B has different length, we just need to fastwind the 'longger' list till their remain length are the same, then we can compare each node on the two lists to find the intersection node.
Algo:
class Solution {
public:
ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
if (!headA || !headB)
return NULL;
int lenA = 1;
int lenB = 1;
ListNode* nodeA = headA;
ListNode* nodeB = headB;
while (nodeA && nodeA->next) {
lenA++;
nodeA = nodeA->next;
}
while (nodeB && nodeB->next) {
lenB++;
nodeB = nodeB->next;
}
if (nodeA != nodeB)
return NULL;
ListNode* longList = NULL;
ListNode* shortList = NULL;
if (lenA > lenB) {
longList = headA;
shortList = headB;
} else {
longList = headB;
shortList = headA;
}
int delta = abs(lenA - lenB);
while (delta--) {
longList = longList->next;
}
while (longList && shortList) {
if (longList == shortList)
break;
longList = longList->next;
shortList = shortList->next;
}
return longList;
}
};
O(M+N)
O(1)
The previouse solution has O(M+N) time complexity and O(1) space complexity, but the code is quite long and error prone. We could use an even simpler approach.
Let's say the length of the common list is lenC. The length of the exclusive partion of the listA is lenA The length of the exclusive partion of the listB is lenB.
We know that lenA + lenC + lenB = lenB + lenC + lenA
So we can simplify the solution: pA point to the head of list A pB point to the head of list B. if pA reach the end of list A, point pA to list B. if pB reach the end of list B, point pB to list A. when pA == pB, we have found the intersection.
class Solution {
public:
ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
ListNode* pA = headA;
ListNode* pB = headB;
while (pA != pB) {
pA = pA? pA->next : headB;
pB = pB? pB->next : headA;
}
return pA;
}
};
O(M+N)
O(1)
class Solution:
def getIntersectionNode(self, headA: ListNode, headB: ListNode) -> ListNode:
if not headA or not headB:
return None
pa, pb = headA, headB
while pa != pb:
pa = headB if not pa else pa.next
pb = headA if not pb else pb.next
return pa
双指针 同时遍历a,b链表,当遍历到a末尾,重定位到b链表头,当遍历到b末尾,重定位到a链表头,如过有a等于b 返回该节点,如果有a等于b等于Null,说明没有交点
java
public class Solution {
public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
ListNode a = headA;
ListNode b = headB;
while(a != b){
a = a.next;
b = b.next;
if(a == null && b == null){
return null;
}
if(a == null){
a = headB;
}
if(b == null){
b = headA;
}
}
return a;
}
}
时间复杂度O(n+m) n:a链表长度,m:b链表长度 空间复杂度O(1)
a1->a2->c1->c2->b1->b2->b3->c1->c2 b1->b2->b3->c1->c2->a1->a2->c1->c2
class Solution(object):
def getIntersectionNode(self, headA, headB):
"""
:type head1, head1: ListNode
:rtype: ListNode
"""
if not headA or not headB:
return None
cur1=headA
cur2=headB
while cur1!=cur2:
if cur1:
cur1=cur1.next
else:
cur1 = headB
if cur2:
cur2=cur2.next
else:
cur2 = headA
return cur1
时间复杂度: O(M+N) 空间复杂度: O(1)
n1+n2 - s = n2+n1 - s (n1,n2分别为链表长度,s为交叉点之后的路径长度)
func getIntersectionNode(headA, headB *ListNode) *ListNode {
if headA == nil || headB == nil {
return nil
}
dummyA := headA
dummyB := headB
for headA != headB {
if headA.Next == nil && headB.Next == nil {
return nil
}
if headA.Next == nil {
headA = dummyB
} else {
headA = headA.Next
}
if headB.Next == nil {
headB = dummyA
} else {
headB = headB.Next
}
}
return headA
}
复杂度分析
双指针。heada
, headb
分别为两个链表lista
, listb
的头指针。
pa = heada
, pb = headb
。pa
不空, 则pa = pa -> next
, 否则 pa = headb
。同理pb
。pa == pb
推出循环。则 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){
if(pa){
pa = pa ->next;
}else{
pa = headB;
}
if(pb){
pb = pb -> next;
}else{
pb = headA;
}
}
return pa;
}
};
遍历两个单链表,可以用hashset存储headA,再判断headB中是否有交点。
class Solution {
public:
ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
unordered_set<ListNode*> visited;
ListNode* temp = headA;
while (temp != nullptr) {
visited.insert(temp);
temp = temp->next;
}
temp = headB;
while (temp != nullptr) {
if (visited.count(temp)) return temp;
temp = temp->next;
}
return nullptr;
}
};
双指针,同时遍历headA + headB,headB + headA,如有交点一定会有相等的节点。
class Solution {
public:
ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
ListNode* A = headA;
ListNode* B = headB;
while (A != B) {
A = A != nullptr ? A->next : headB;
B = B != nullptr ? B->next : headA;
}
return A;
}
};
Python3 Code:
class Solution:
def getIntersectionNode(self, headA: ListNode, headB: ListNode) -> ListNode:
if not headA or not headB:
return None
pa, pb = headA, headB
while pa != pb:
pa = pa.next if pa else headB
pb = pb.next if pb else headA
return pa
复杂度分析
Time: O(len(A) + len(B) - len(common(A, B))
Space: O(1)
占坑稍等回答
1. Check the condition if either of the list is empty.
class Solution:
def getIntersectionNode(self, headA: ListNode, headB: ListNode) -> ListNode:
node_in_A = set()
while headA is not None:
node_in_A.add(headA)
headA = headA.next
while headB is not None:
#If in the node_a_set we found headB, we return the node
if headB in node_in_A:
return headB
headB = headB.next
return None
NA
def getIntersectionNode(self, headA: ListNode, headB: ListNode) -> ListNode:
if not headA or not headB:
return None
pA = headA
pB = headB
while (pA != pB):
if pA is None:
pA = headB
else:
pA = pA.next
if pB is None:
pB = headA
else:
pB = pB.next
return pA
Time Complexity O(N+M), If they don't have intersection nodes, the worst case is that we need to traverse the lists twice.The path for one node is a+b -c, and there is no c. O(2M+2N) = O(M+N). When they have the same length, we only need to do traverse each list once.
Space Complexity O(1) Since we didn't use any additional data structures. The amount of space does not grow beyond the size of inputs.
public class Solution {
public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
ListNode a=headA;
ListNode b=headB;
while(a!=b)
{
if(a==null)
a=headB;
else
a=a.next;
if(b==null)
b=headA;
else
b=b.next;
}
return a;
}
}
时间复杂度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 == nullptr || headB == nullptr) return nullptr;
ListNode* pA = headA;
ListNode* pB = headB;
while(pA != pB){
if (pA == nullptr){
pA = headB;
} else {
pA = pA->next;
}
if (pB == nullptr){
pB = headA;
} else {
pB = pB->next;
}
}
return pA;
}
};
class Solution:
def getIntersectionNode(self, headA: ListNode, headB: ListNode) -> ListNode:
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(object):
def getIntersectionNode(self, headA, headB):
"""
:type head1, head1: ListNode
:rtype: ListNode
"""
a_len, b_len = 0, 0
pa, pb = headA, headB
while pa:
pa = pa.next
a_len += 1
while pb:
pb = pb.next
b_len += 1
pmax = headB if b_len > a_len else headA
pmin = headB if b_len <= a_len else headA
diff = abs(a_len-b_len)
while diff > 0:
pmax = pmax.next
diff -= 1
while pmin:
if pmin == pmax:
return pmin
else:
pmin = pmin.next
pmax = pmax.next
return None
var getIntersectionNode = function(headA, headB) {
let nodeA=headA;
let nodeB=headB;
while(nodeA&&nodeB){
if(nodeA===nodeB){
return nodeA
}
nodeA=nodeA.next;
nodeB=nodeB.next;
if(nodeA===null&&nodeB){
nodeA=headB
}
if(nodeB===null&&nodeA){
nodeB=headA
}
}
return null
};
时间复杂度:o(n+m),空间o(1)
传统思路,这期我的重点在锻炼写c++而不是思路上,所以就不写思路了(^▽^) Apex的服务器啥时候能修好啊
set就是hashmap/哈希表的一种;
此处的是没有顺序的。JS的一般默认是有序的:D
根据Lucifer的建议改进了一下,添加了数哪个list更小的countWhoIsSmaller
。
根据更小的结果来选择谁作为哈希表(unsorted_set
)的存储对象,以达到优化空间的目的。
当然这个优化不是必须的。
class Solution {
public:
ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
unordered_set<ListNode *>visited;
std::string result = countWhoIsSmaller(headA, headB);
ListNode *temp = result == "A" ? headA : headB;
while(temp != nullptr){
visited.insert(temp);
temp = temp->next;
}
temp = result == "A" ? headB : headA;
while(temp != nullptr){
if(visited.count(temp)){
return temp;
}
temp = temp->next;
}
return nullptr;
}
private:
std::string countWhoIsSmaller(ListNode *headA, ListNode *headB){
int sizeA = 0, sizeB = 0;
ListNode *count = headA;
while(count != nullptr){
sizeA++;
count = count->next;
}
count = headB;
while(count != nullptr){
sizeB++;
count = count->next;
}
if (sizeA >= sizeB){
return "B";
}else{
return "A";
}
}
};
时间复杂度:O(n + m) n is the size of the list that starts with HeadA, m is ... headB
空间复杂度:O(min(m,n))
class Solution {
public:
ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
if(headA == nullptr || headB == nullptr){
return nullptr;
}
ListNode *pa = headA, *pb = headB;
while(pa != pb){
pa = pa == nullptr ? headB : pa->next;
pb = pb == nullptr ? headA : pb->next;
}
return pa;
}
};
时间复杂度:O(n + m)
空间复杂度:O(1)
160. 相交链表
入选理由
暂无
题目地址
https://leetcode-cn.com/problems/intersection-of-two-linked-lists/
前置知识
题目描述