?劍指 Offer 52. 兩個(gè)鏈表的第一個(gè)公共節(jié)點(diǎn)
難度:簡(jiǎn)單
輸入兩個(gè)鏈表,找出它們的第一個(gè)公共節(jié)點(diǎn)。
如下面的兩個(gè)鏈表:
在節(jié)點(diǎn) c1 開始相交。
示例 1:
輸入:intersectVal = 8, listA = [4,1,8,4,5], listB = [5,0,1,8,4,5], skipA = 2, skipB = 3
輸出:Reference of the node with value = 8
輸入解釋:相交節(jié)點(diǎn)的值為 8 (注意,如果兩個(gè)列表相交則不能為 0)。從各自的表頭開始算起,鏈表 A 為 [4,1,8,4,5],鏈表 B 為 [5,0,1,8,4,5]。在 A 中,相交節(jié)點(diǎn)前有 2 個(gè)節(jié)點(diǎn);在 B 中,相交節(jié)點(diǎn)前有 3 個(gè)節(jié)點(diǎn)。
示例 2:
輸入:intersectVal = 2, listA = [0,9,1,2,4], listB = [3,2,4], skipA = 3, skipB = 1
輸出:Reference of the node with value = 2
輸入解釋:相交節(jié)點(diǎn)的值為 2 (注意,如果兩個(gè)列表相交則不能為 0)。從各自的表頭開始算起,鏈表 A 為 [0,9,1,2,4],鏈表 B 為 [3,2,4]。在 A 中,相交節(jié)點(diǎn)前有 3 個(gè)節(jié)點(diǎn);在 B 中,相交節(jié)點(diǎn)前有 1 個(gè)節(jié)點(diǎn)。
示例 3:
輸入:intersectVal = 0, listA = [2,6,4], listB = [1,5], skipA = 3, skipB = 2
輸出:null
輸入解釋:從各自的表頭開始算起,鏈表 A 為 [2,6,4],鏈表 B 為 [1,5]。由于這兩個(gè)鏈表不相交,所以 intersectVal 必須為 0,而 skipA 和 skipB 可以是任意值。
解釋:這兩個(gè)鏈表不相交,因此返回 null。
注意:
- 如果兩個(gè)鏈表沒有交點(diǎn),返回
null
. - 在返回結(jié)果后,兩個(gè)鏈表仍須保持原有的結(jié)構(gòu)。
- 可假定整個(gè)鏈表結(jié)構(gòu)中沒有循環(huán)。
- 程序盡量滿足 O ( n ) O(n) O(n) 時(shí)間復(fù)雜度,且僅用 O ( 1 ) O(1) O(1) 內(nèi)存。
- 本題與160. 相交鏈表相同。
??思路:雙指針
設(shè) A
的長(zhǎng)度為 a
+ c
,B
的長(zhǎng)度為 b
+ c
,其中 c
為尾部公共部分長(zhǎng)度,可知:
a
+
c
+
b
=
b
+
c
+
a
a + c + b = b + c + a
a+c+b=b+c+a
- 當(dāng)訪問鏈表
A
的指針訪問到鏈表尾部時(shí),令它從鏈表B
的頭部重新開始訪問鏈表B
; - 同樣地,當(dāng)訪問鏈表
B
的指針訪問到鏈表尾部時(shí),令它從鏈表A
的頭部重新開始訪問鏈表A
。
這樣就能控制訪問 A
和 B
兩個(gè)鏈表的指針能同時(shí)訪問到交點(diǎn)。
??代碼:(C++、Java)
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* cur1 = headA;
ListNode* cur2 = headB;
while(cur1 != cur2){
cur1 = (cur1 == nullptr) ? headB : cur1->next;
cur2 = (cur2 == nullptr) ? headA : cur2->next;
}
return cur1;
}
};
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 cur1 = headA, cur2 = headB;
while(cur1 != cur2){
cur1 = (cur1 == null) ? headB : cur1.next;
cur2 = (cur2 == null) ? headA : cur2.next;
}
return cur1;
}
}
?? 運(yùn)行結(jié)果:
?? 復(fù)雜度分析:
-
時(shí)間復(fù)雜度:
O
(
m
+
n
)
O(m+n)
O(m+n),其中
m
和n
是分別是鏈表headA
和headB
的長(zhǎng)度。兩個(gè)指針同時(shí)遍歷兩個(gè)鏈表,每個(gè)指針遍歷兩個(gè)鏈表各一次。 - 空間復(fù)雜度: O ( 1 ) O(1) O(1)。
題目來源:力扣。文章來源:http://www.zghlxwxcb.cn/news/detail-613403.html
放棄一件事很容易,每天能堅(jiān)持一件事一定很酷,一起每日一題吧!
關(guān)注我LeetCode主頁 / CSDN—力扣專欄,每日更新!文章來源地址http://www.zghlxwxcb.cn/news/detail-613403.html
注: 如有不足,歡迎指正!
到了這里,關(guān)于(鏈表) 劍指 Offer 52. 兩個(gè)鏈表的第一個(gè)公共節(jié)點(diǎn) ——【Leetcode每日一題】的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!