日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

leetcode题目解析(js)--链表

發(fā)布時(shí)間:2025/3/8 编程问答 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 leetcode题目解析(js)--链表 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

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), 主要邏輯分三步:

  • 修改cur的next,指向前一個(gè)節(jié)點(diǎn),即prev
  • 保存當(dāng)前節(jié)點(diǎn)cur為prev,供下一個(gè)節(jié)點(diǎn)使用
  • 移動(dòng)當(dāng)前節(jié)點(diǎn)指針cur到下一個(gè)節(jié)點(diǎn)cur.next
  • 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ù)制代碼

    解題思路:

  • 先用快慢指針方法確定鏈表是否有環(huán)
  • 如果有環(huán)的,慢指針slow重新從head出發(fā),slow,fast每次都走一步,如果重合,重合處必為環(huán)的入口;
  • 入口解釋一下:

    首先第一次遍歷后假設(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)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。