摘要:還是鏈表算法題目描述給出兩個(gè)無環(huán)單鏈表判斷和是否相交。所以可以得出另外一種解法,先遍歷鏈表,記住尾節(jié)點(diǎn),然后遍歷鏈表,比較兩個(gè)鏈表的尾節(jié)點(diǎn),如果相同則相交,不同則不相交。想法還是奇妙的。算法寫起來不難,難的是想到這個(gè)。
還是鏈表算法
題目描述:給出兩個(gè)無環(huán)單鏈表
A: a1 → a2
↘ c1 → c2 → c3 → null ↗
B: b1 → b2 → b3
判斷 A 和 B 是否相交。
除了轉(zhuǎn)化為環(huán)的問題,還可以利用“如果兩個(gè)鏈表相交于某一節(jié)點(diǎn),那么之后的節(jié)點(diǎn)都是共有的”這個(gè)特點(diǎn),如果兩個(gè)鏈表相交,那么最后一個(gè)節(jié)點(diǎn)一定是共有的。所以可以得出另外一種解法,先遍歷 A 鏈表,記住尾節(jié)點(diǎn),然后遍歷 B 鏈表,比較兩個(gè)鏈表的尾節(jié)點(diǎn),如果相同則相交,不同則不相交。時(shí)間復(fù)雜度為 O(Length(A) + Length(B)),空間復(fù)雜度為 O(1),思路比解法 2 更簡單。想法還是奇妙的。算法寫起來不難,難的是想到這個(gè)。
function hasSharedNode(head1, head2){ if(head1 == null||head2 == null) return false; var lastNode1 = head1; while(lastNode1.next != null){ lastNode1 = lastNode1.next; } var lastNode2 = head2; while(lastNode2.next != null){ lastNode2 = lastNode2.next; } if(lastNode1 == lastNode2){ return true; } else { return false; } }
兩個(gè)鏈表相交擴(kuò)展:判斷兩個(gè)有環(huán)單鏈表是否相交
題目描述:上面的問題是針對(duì)無環(huán)鏈表的,如果是鏈表有環(huán)呢?
分析:如果兩個(gè)有環(huán)單鏈表相交,那么它們一定共有一個(gè)環(huán)。因此可以先用之前快慢指針的方式找到兩個(gè)鏈表中位于環(huán)內(nèi)的兩個(gè)節(jié)點(diǎn),如果相交的話,兩個(gè)節(jié)點(diǎn)在一個(gè)環(huán)內(nèi),那么移動(dòng)其中一個(gè)節(jié)點(diǎn),在一次循環(huán)內(nèi)肯定可以與另外一個(gè)節(jié)點(diǎn)相遇。
有環(huán)單鏈表到底是咋樣的,就是我們前面說的小b型的結(jié)構(gòu)吧。尾節(jié)點(diǎn)的next指向前面的某個(gè)節(jié)點(diǎn)。如果交點(diǎn)不是在環(huán)上,那么肯定是共享一段直線加上一個(gè)環(huán)。
如果交點(diǎn)是在環(huán)上,那么就是共享環(huán),直線階段是各自獨(dú)立的。所以結(jié)果就是共有一個(gè)環(huán)。需要用到上次找環(huán)入口的那個(gè)function。為啥不能用無環(huán)鏈表的算法呢?因?yàn)闆]法判斷尾節(jié)點(diǎn)。其實(shí)也算是用到了,其實(shí)環(huán)入口就算是尾節(jié)點(diǎn)吧。
function findLoopPort(head){ if(head==null||head.next==null) return null; var fastNode = head; var normalNode = head; var hasCircle = false; while(fastNode != null&&fastNode.next != null){ fastNode = fastNode.next.next; normalNode = normalNode.next; if(normalNode == fastNode) { hasCircle = true; break; } } if(!hasCircle) return null;//原本想return false,后來發(fā)現(xiàn)還是null好。 var fastNode = head; while(fastNode != normalNode){ fastNode = fastNode.next; normalNode = normalNode.next; } return fastNode; } function hasSharedNodeWithLoop(head1, head2){ var loopPort1 = findLoopPort(head1); //head1 head2的null之類的已經(jīng)在findLoopPort里面判斷了。 var loopPort2 = findLoopPort(head2); if(loopPort1 == null || loopPort2 == null){ //無環(huán),則不滿足條件,即使無環(huán)單鏈表相交,也返回false return false; } var startNode = loopPort1; while(loopPort1.next != startNode){ //保證只在環(huán)內(nèi)轉(zhuǎn)一圈 if(loopPort1 == loopPort2) return true; loopPort1 = loopPort1.next; } return false; //轉(zhuǎn)完一圈沒發(fā)現(xiàn)共同的節(jié)點(diǎn),則沒相交點(diǎn)。 }
兩個(gè)鏈表相交擴(kuò)展:求兩個(gè)無環(huán)單鏈表的第一個(gè)相交點(diǎn)
LeetCode 160. Intersection of Two Linked Lists
題目描述:找到兩個(gè)無環(huán)單鏈表第一個(gè)相交點(diǎn),如果不相交返回空,要求在線性時(shí)間復(fù)雜度和常量空間復(fù)雜度內(nèi)完成。我的想法是如果求得最后一個(gè)尾節(jié)點(diǎn),然后讓尾節(jié)點(diǎn)的next指向其中的一個(gè)的頭,那么肯定就構(gòu)成了一個(gè)有環(huán)單鏈表。然后求得環(huán)的入口就是第一個(gè)相交點(diǎn)。主要是感覺一步一步的,好像都在復(fù)用前面的東西。所以就想到了這個(gè)。
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/90233.html
摘要:強(qiáng)烈推薦上值得前端學(xué)習(xí)的數(shù)據(jù)結(jié)構(gòu)與算法項(xiàng)目,包含圖的演示過程與視頻講解。該倉庫包含了多種基于的算法與數(shù)據(jù)結(jié)構(gòu),提供進(jìn)一步閱讀的解釋和鏈接。數(shù)據(jù)結(jié)構(gòu)和算法必知必會(huì)的個(gè)代碼實(shí)現(xiàn)。 showImg(https://segmentfault.com/img/bVbvpYZ); 前言 算法為王。想學(xué)好前端,先練好內(nèi)功,內(nèi)功不行,就算招式練的再花哨,終究成不了高手;只有內(nèi)功深厚者,前端之路才會(huì)走得...
摘要:算法系列單源最短路徑算法迪杰斯特拉算法是由荷蘭計(jì)算機(jī)科學(xué)家狄克斯特拉于年提出的,因此又叫狄克斯特拉算法。是從一個(gè)頂點(diǎn)到其余各頂點(diǎn)的最短路徑算法,解決的是有向圖中最短路徑問題。 Javascript算法系列 - 單源最短路徑 - Dijkstra算法 迪杰斯特拉算法是由荷蘭計(jì)算機(jī)科學(xué)家狄克斯特拉于1959年提出的,因此又叫狄克斯特拉算法。是從一個(gè)頂點(diǎn)到其余各頂點(diǎn)的最短路徑算法,解決的是有...
摘要:因?yàn)槭窃谝呀?jīng)分組排序過的基礎(chǔ)上進(jìn)行插入排序,所以效率高。本質(zhì)上來看,快速排序應(yīng)該算是在冒泡排序基礎(chǔ)上的遞歸分治法。形成左右兩個(gè)分區(qū),再遞歸按之前的步驟排序。 算法復(fù)雜度 不是科班生的我,第一次看見時(shí)間復(fù)雜度之類的名詞表示很懵逼,所以就找了網(wǎng)上的資料補(bǔ)習(xí)了下: 時(shí)間復(fù)雜度:是指執(zhí)行算法所需要的計(jì)算工作量 空間復(fù)雜度:是指算法在計(jì)算機(jī)內(nèi)執(zhí)行時(shí)所需存儲(chǔ)空間的度量 排序算法穩(wěn)定性: 假定在待...
摘要:回顧選擇排序,插入排序,冒泡排序,快速排序,希爾排序,歸并排序,堆排序以及如何計(jì)算時(shí)間復(fù)雜度學(xué)習(xí)文章同學(xué)的描述數(shù)據(jù)結(jié)構(gòu)等同學(xué)的十大經(jīng)典算法本文代碼也上傳到了排序算法回顧。但希爾排序是非穩(wěn)定排序算法。 回顧選擇排序,插入排序,冒泡排序,快速排序,希爾排序,歸并排序,堆排序以及如何計(jì)算時(shí)間復(fù)雜度學(xué)習(xí)文章:hahda同學(xué)的javascript描述數(shù)據(jù)結(jié)構(gòu)、hustcc等同學(xué)的十大經(jīng)典算法 ...
摘要:筆者寫的數(shù)據(jù)結(jié)構(gòu)與算法之美系列用的語言是,旨在入門數(shù)據(jù)結(jié)構(gòu)與算法和方便以后復(fù)習(xí)。這應(yīng)該是目前較為簡單的十大經(jīng)典排序算法的文章講解了吧。比如原本在的前面,而,排序之后,在的后面十大經(jīng)典排序算法冒泡排序思想冒泡排序只會(huì)操作相鄰的兩個(gè)數(shù)據(jù)。 showImg(https://segmentfault.com/img/bVbvHet); 1. 前言 算法為王。想學(xué)好前端,先練好內(nèi)功,內(nèi)功不行,就...
摘要:之所以把冒泡排序選擇排序插入排序放在一起比較,是因?yàn)樗鼈兊钠骄鶗r(shí)間復(fù)雜度都為。其中,冒泡排序就是原地排序算法。所以冒泡排序是穩(wěn)定的排序算法。選擇排序思路選擇排序算法的實(shí)現(xiàn)思路有點(diǎn)類似插入排序,也分已排序區(qū)間和未排序區(qū)間。 showImg(https://segmentfault.com/img/bVbuvnj?w=900&h=250); 1. 前言 算法為王。 想學(xué)好前端,先練好內(nèi)功,...
閱讀 3505·2021-09-02 09:53
閱讀 1830·2021-08-26 14:13
閱讀 2789·2019-08-30 15:44
閱讀 1348·2019-08-30 14:03
閱讀 2005·2019-08-26 13:42
閱讀 3046·2019-08-26 12:21
閱讀 1333·2019-08-26 11:54
閱讀 1927·2019-08-26 10:46