leetcode题目解析(js)--链表
206. 反轉(zhuǎn)鏈表
反轉(zhuǎn)一個(gè)單鏈表。
示例:
輸入: 1->2->3->4->5->NULL
輸出: 5->4->3->2->1->NULL
解法:
var reverseList = function(head) {let cur = head, prev = nullwhile(cur) {[cur.next, prev, cur] = [prev, cur, cur.next]}return prev }; 復(fù)制代碼思路分析:prev保存前一個(gè)節(jié)點(diǎn), 主要邏輯分三步:
24. 兩兩交換鏈表中的節(jié)點(diǎn)
給定一個(gè)鏈表,兩兩交換其中相鄰的節(jié)點(diǎn),并返回交換后的鏈表。 你不能只是單純的改變節(jié)點(diǎn)內(nèi)部的值,而是需要實(shí)際的進(jìn)行節(jié)點(diǎn)交換。
示例:
給定 1->2->3->4, 你應(yīng)該返回 2->1->4->3.
解法一:
var swapPairs = function(head) {let node = new ListNode(0) //新建一個(gè)節(jié)點(diǎn),用于保存head節(jié)點(diǎn)node.next = headlet prev = nodewhile(prev.next && prev.next.next) {let a = prev.nextlet b = a.nextprev.next = a.nexta.next = b.nextprev = b.next = a}return node.next }; 復(fù)制代碼解題思路: 定義一個(gè)新的頭節(jié)點(diǎn)node,將頭節(jié)點(diǎn)next指向head,定義prev, a, b分別指向前三項(xiàng),第一遍循環(huán)如下圖:
循環(huán)過程中node始終指向自定義的頭結(jié)點(diǎn),而node.next即為真正的頭節(jié)點(diǎn)。遍歷第二遍時(shí),a, b分別指向3,4,執(zhí)行流程同上,執(zhí)行完第二遍即結(jié)束循環(huán)。
解法二:
var swapPairs = function(head) {if(!head) return nullif(!head.next) return headlet temp = head.nexthead.next = swapPairs(temp.next)temp.next = headreturn temp }; 復(fù)制代碼解題思路:主要邏輯是head.next指向遞歸返回的上一個(gè)temp,同時(shí)修改temp.next為head,實(shí)現(xiàn)后一個(gè)節(jié)點(diǎn)指向前一個(gè)節(jié)點(diǎn),同時(shí)前一個(gè)節(jié)點(diǎn)指向遞歸返回的節(jié)點(diǎn),最后swapPairs接收到的就是最后返回的temp,即第二個(gè)節(jié)點(diǎn)2.
141. 環(huán)形鏈表
給定一個(gè)鏈表,判斷鏈表中是否有環(huán)。
示例:
輸入:head = [3,2,0,-4], 輸出:true
解法一:使用快慢指針,快指針每次走兩步,慢指針每次走一步,如果有環(huán),二者必定會(huì)碰到一起;
var hasCycle = function(head) {let fast = slow = headwhile(fast && slow && fast.next) { //fast.next不存在說明鏈表已走完slow = slow.nextfast = fast.next.nextif(fast === slow) {return true}}return false }; 復(fù)制代碼解法二:使用Set保存每個(gè)節(jié)點(diǎn)的地址,如果有環(huán),Set里元素必定會(huì)重復(fù);
var hasCycle = function(head) {let set = new Set()while(head) {if(set.has(head)) return trueset.add(head)head = head.next}return false }; 復(fù)制代碼142. 環(huán)形鏈表 II
給定一個(gè)鏈表,返回鏈表開始入環(huán)的第一個(gè)節(jié)點(diǎn)。 如果鏈表無環(huán),則返回 null
示例:
輸入:head = [3,2,0,-4]
輸出:tail connects to node index 1
解法一:
var detectCycle = function(head) {let set = new Set()let cur = headwhile(cur) {if(set.has(cur)) return curset.add(cur)cur = cur.next}return null }; 復(fù)制代碼解題思路:用Set保存每次遍歷的地址,遍歷時(shí)發(fā)現(xiàn)地址重復(fù)即為入口節(jié)點(diǎn)
解法二:
var detectCycle = function(head) {let fast = slow = headwhile(slow && fast && fast.next) {slow = slow.nextfast = fast.next.nextif(slow === fast) {slow = headwhile(slow !== fast) {slow = slow.nextfast = fast.next}return fast}}return null }; 復(fù)制代碼解題思路:
入口解釋一下:
首先第一次遍歷后假設(shè)在C點(diǎn)相遇,此時(shí):
慢指針走的S1 = |AB| + |BC|
快指針走的S2 = 2 * ( |AB| + |BC| )
在另一個(gè)角度,S2 走的距離就是 |AB| + |BC| + n * s (s為環(huán)的大小),即
快指針走的S2 = |AB| + |BC| + n * s
所以可以得到
2 * ( |AB| + |BC| ) = |AB| + |BC| + n * s
可以得到:|AB| = n * s - |BC|
可以看出如果slow從A點(diǎn)開始,fast從相遇點(diǎn)C開始,兩者以同樣速度必會(huì)在B點(diǎn)相遇
總結(jié)
以上是生活随笔為你收集整理的leetcode题目解析(js)--链表的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: AI大神贾扬清确认将离开Facebook
- 下一篇: 理解webpack原理,手写一个100行