C++實(shí)現(xiàn)LeetCode(160.求兩個(gè)鏈表的交點(diǎn))
[LeetCode] 160.Intersection of Two Linked Lists 求兩個(gè)鏈表的交點(diǎn)
Write a program to find the node at which the intersection of two singly linked lists begins.
For example, the following two linked lists:
A: a1 → a2
↘
c1 → c2 → c3
↗
B: b1 → b2 → b3
begin to intersect at node c1.
Notes:
- If the two linked lists have no intersection at all, return null.
- The linked lists must retain their original structure after the function returns.
- You may assume there are no cycles anywhere in the entire linked structure.
- Your code should preferably run in O(n) time and use only O(1) memory.
Credits:
Special thanks to @stellari for adding this problem and creating all test cases.
我還以為以后在不能免費(fèi)做OJ的題了呢,想不到 OJ 又放出了不需要買書就能做的題,業(yè)界良心啊,哈哈^_^。這道求兩個(gè)鏈表的交點(diǎn)題要求執(zhí)行時(shí)間為 O(n),則不能利用類似冒泡法原理去暴力查找相同點(diǎn),事實(shí)證明如果鏈表很長(zhǎng)的話,那樣的方法效率很低。我也想到會(huì)不會(huì)是像之前刪除重復(fù)元素的題一樣需要用兩個(gè)指針來遍歷,可是想了好久也沒想出來怎么弄。無奈上網(wǎng)搜大神們的解法,發(fā)覺其實(shí)解法很簡(jiǎn)單,因?yàn)槿绻麅蓚€(gè)鏈長(zhǎng)度相同的話,那么對(duì)應(yīng)的一個(gè)個(gè)比下去就能找到,所以只需要把長(zhǎng)鏈表變短即可。具體算法為:分別遍歷兩個(gè)鏈表,得到分別對(duì)應(yīng)的長(zhǎng)度。然后求長(zhǎng)度的差值,把較長(zhǎng)的那個(gè)鏈表向后移動(dòng)這個(gè)差值的個(gè)數(shù),然后一一比較即可。代碼如下:
C++ 解法一:
class Solution {
public:
ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
if (!headA || !headB) return NULL;
int lenA = getLength(headA), lenB = getLength(headB);
if (lenA < lenB) {
for (int i = 0; i < lenB - lenA; ++i) headB = headB->next;
} else {
for (int i = 0; i < lenA - lenB; ++i) headA = headA->next;
}
while (headA && headB && headA != headB) {
headA = headA->next;
headB = headB->next;
}
return (headA && headB) ? headA : NULL;
}
int getLength(ListNode* head) {
int cnt = 0;
while (head) {
++cnt;
head = head->next;
}
return cnt;
}
};
Java 解法一:
public class Solution {
public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
if (headA == null || headB == null) return null;
int lenA = getLength(headA), lenB = getLength(headB);
if (lenA > lenB) {
for (int i = 0; i < lenA - lenB; ++i) headA = headA.next;
} else {
for (int i = 0; i < lenB - lenA; ++i) headB = headB.next;
}
while (headA != null && headB != null && headA != headB) {
headA = headA.next;
headB = headB.next;
}
return (headA != null && headB != null) ? headA : null;
}
public int getLength(ListNode head) {
int cnt = 0;
while (head != null) {
++cnt;
head = head.next;
}
return cnt;
}
}
這道題還有一種特別巧妙的方法,雖然題目中強(qiáng)調(diào)了鏈表中不存在環(huán),但是我們可以用環(huán)的思想來做,我們讓兩條鏈表分別從各自的開頭開始往后遍歷,當(dāng)其中一條遍歷到末尾時(shí),我們跳到另一個(gè)條鏈表的開頭繼續(xù)遍歷。兩個(gè)指針最終會(huì)相等,而且只有兩種情況,一種情況是在交點(diǎn)處相遇,另一種情況是在各自的末尾的空節(jié)點(diǎn)處相等。為什么一定會(huì)相等呢,因?yàn)閮蓚€(gè)指針走過的路程相同,是兩個(gè)鏈表的長(zhǎng)度之和,所以一定會(huì)相等。這個(gè)思路真的很巧妙,而且更重要的是代碼寫起來特別的簡(jiǎn)潔,參見代碼如下:
C++ 解法二:
class Solution {
public:
ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
if (!headA || !headB) return NULL;
ListNode *a = headA, *b = headB;
while (a != b) {
a = a ? a->next : headB;
b = b ? b->next : headA;
}
return a;
}
};
Java 解法二:
public 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 = (a != null) ? a.next : headB;
b = (b != null) ? b.next : headA;
}
return a;
}
}
類似題目:
Minimum Index Sum of Two Lists
參考資料:
https://leetcode.com/problems/intersection-of-two-linked-lists/
到此這篇關(guān)于C++實(shí)現(xiàn)LeetCode(160.求兩個(gè)鏈表的交點(diǎn))的文章就介紹到這了,更多相關(guān)C++實(shí)現(xiàn)求兩個(gè)鏈表的交點(diǎn)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
C++?shared_ptr智能指針reset()使用示例詳解
這篇文章主要為大家介紹了C++?shared_ptr智能指針reset()使用示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-08-08
C語言實(shí)現(xiàn)24點(diǎn)游戲計(jì)算器的示例代碼
24點(diǎn)是一種益智游戲,24點(diǎn)是把4個(gè)整數(shù)(一般是正整數(shù))通過加減乘除以及括號(hào)運(yùn)算,使最后的計(jì)算結(jié)果是24的一個(gè)數(shù)學(xué)游戲,24點(diǎn)可以考驗(yàn)人的智力和數(shù)學(xué)敏感性,它能在游戲中提高人們的心算能力。本文將用C語言實(shí)現(xiàn)這一游戲,感興趣的可以了解一下2022-08-08
C語言中結(jié)構(gòu)體的內(nèi)存對(duì)齊規(guī)則講解
C 數(shù)組允許定義可存儲(chǔ)相同類型數(shù)據(jù)項(xiàng)的變量,結(jié)構(gòu)是 C 編程中另一種用戶自定義的可用的數(shù)據(jù)類型,它允許你存儲(chǔ)不同類型的數(shù)據(jù)項(xiàng),本篇讓我們來了解C 的結(jié)構(gòu)體內(nèi)存對(duì)齊2022-05-05
C語言每日練習(xí)之動(dòng)態(tài)顯示系統(tǒng)時(shí)間
這篇文章主要介紹了C語言動(dòng)態(tài)顯示系統(tǒng)時(shí),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2021-11-11
C語言實(shí)現(xiàn)可增容動(dòng)態(tài)通訊錄詳細(xì)過程
這篇文章主要為大家介紹了C語言實(shí)現(xiàn)簡(jiǎn)易通訊錄的完整流程,此通訊錄還可以增容,并且每個(gè)環(huán)節(jié)都有完整代碼,有需要的朋友可以借鑒參考下,希望能夠有所幫助2022-05-05
CreateThread()與beginthread()的區(qū)別詳細(xì)解析
很多開發(fā)者不清楚這兩者之間的關(guān)系,他們隨意選一個(gè)函數(shù)來用,發(fā)現(xiàn)也沒有什么大問題,于是就忙于解決更為緊迫的任務(wù)去了。等到有一天忽然發(fā)現(xiàn)一個(gè)程序運(yùn)行時(shí)間很長(zhǎng)的時(shí)候會(huì)有細(xì)微的內(nèi)存泄露,開發(fā)者絕對(duì)不會(huì)想到是因?yàn)檫@兩套函數(shù)用混的結(jié)果2013-09-09
C++異步操作future和aysnc與function和bind
這篇文章主要介紹了C++異步操作future和aysnc與function和bind,文章圍繞主題展開詳細(xì)的內(nèi)容介紹,具有一定的參考價(jià)值,需要的小伙伴可以參考一下2022-09-09

