自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

鏈表基礎(chǔ)之LeetCode題解

開發(fā) 前端
鏈表是一種物理存儲單元上非連續(xù)、非順序的存儲結(jié)構(gòu)。由于不必須按順序存儲,鏈表的插入和刪除操作可以達到O(1)的復(fù)雜

[[377395]]

前言

今天繼續(xù)算法題:從尾到頭打印鏈表

鏈表

在看今天題目之前,我們先了解下鏈表。

鏈表是一種物理存儲單元上非連續(xù)、非順序的存儲結(jié)構(gòu)。由于不必須按順序存儲,鏈表的插入和刪除操作可以達到O(1)的復(fù)雜度

熟悉數(shù)組的都知道,數(shù)組是需要一塊連續(xù)的內(nèi)存空間來存儲。而鏈表就不需要,它是通過指針來將內(nèi)存塊串聯(lián)起來。

常見的鏈表結(jié)構(gòu)有:單鏈表、雙向鏈表和循環(huán)鏈表。(圖片來自參考鏈接)

單鏈表

 

第一個接點為頭結(jié)點,最后一個結(jié)點是尾結(jié)點。

從圖中可以看出來:當(dāng)某個結(jié)點不是指向下一個結(jié)點,而是指向了null,空地址,那么這個結(jié)點就是這個鏈表最后一個結(jié)點,也就是尾結(jié)點。

當(dāng)我們插入或者刪除結(jié)點只需要修改next結(jié)點就行,也就是修改next指針指向地址,比如這樣一個鏈表:

  1. a->next=b, b->next=c, c->next=d 

a下一個結(jié)點是b,b下一個結(jié)點是c...

如果我們要在ab直接插入一個結(jié)點p,得益于鏈表的不連續(xù)性,我們只需要修改a的next為p,p的next為b就行了。

  1. a->next=p, p->next=b, b->next=c, c->next=d 

通俗點說,插入的時候,就修改兩個結(jié)點的跟屁蟲就行啦。所以不同于數(shù)組插入和刪除操作,鏈表的插入和刪除效率很高,不需要考慮空間連續(xù)問題,所以對應(yīng)的時間復(fù)雜度是O(1)。

但是反過來,如果要查詢第n個數(shù)據(jù)為誰,這個就比較麻煩了。不像數(shù)組由于內(nèi)存連續(xù),所以很輕易就知道n對應(yīng)的數(shù)據(jù)。而鏈表需要一個個next查找,所以鏈表隨機訪問的效率就不如數(shù)組了,時間復(fù)雜度為O(n)。

循環(huán)鏈表

 

循環(huán)鏈表和單鏈表的區(qū)別就是,尾結(jié)點指針會指向頭結(jié)點,形成一個環(huán)形,這就是循環(huán)鏈表。

雙向鏈表

 

如圖所示,雙向鏈表和單鏈表的區(qū)別就是,每個結(jié)點不僅有下個結(jié)點的地址,還有上一個結(jié)點的地址。

這樣有什么好處呢?在特定的情境中能提高效率。比如我要在某個結(jié)點B的前面插入數(shù)據(jù),那么我需要從頭開始便利,找到某個結(jié)點的next指向這個B的地址,然后進行數(shù)據(jù)的插入。

但是雙向鏈表則可以直接獲知結(jié)點B的前驅(qū)結(jié)點地址,大大提高了插入效率。

鏈表的基礎(chǔ)知識就介紹到這里了,下面看一個鏈表相關(guān)的算法題。

題目:從尾到頭打印鏈表

輸入一個鏈表的頭節(jié)點,從尾到頭反過來返回每個節(jié)點的值(用數(shù)組返回)。

示例 1:

輸入:head = [1,3,2] 輸出:[2,3,1]

限制:

0 <= 鏈表長度 <= 10000

解法一

題目意思很簡單,就是一個鏈表,現(xiàn)在要先從尾巴倒著打印鏈表的數(shù)字。

那我們就可以想到可以用到遞歸算法,遞歸算法其實就是兩步,先遞后歸,我們可以先傳遞到鏈表的最后一位,也就是next->null為空的時候,然后開始?xì)w檔把數(shù)據(jù)依次輸出,即完成了從結(jié)尾開始輸出數(shù)字的需求了。

  • 遞推階段:走到鏈表結(jié)尾為結(jié)束的標(biāo)志。
  • 歸檔階段:從結(jié)尾處一層層輸出數(shù)字,先輸出到ArrayList,在轉(zhuǎn)為數(shù)組。

不明白的可以看看代碼:

  1. class Solution { 
  2.     ArrayList<Integer> tmp = new ArrayList<Integer>(); 
  3.     public int[] reversePrint(ListNode head) { 
  4.         recur(head); 
  5.         int[] res = new int[tmp.size()]; 
  6.         for(int i = 0; i < res.length; i++) 
  7.             res[i] = tmp.get(i); 
  8.         return res; 
  9.     } 
  10.  
  11.     //遞歸方法 
  12.     void recur(ListNode head) { 
  13.      //到鏈表結(jié)尾處,遞推結(jié)束,開始?xì)w檔,依次輸出 
  14.         if(head == nullreturn
  15.         recur(head.next); 
  16.         tmp.add(head.val); 
  17.     } 

方法消耗情況

  1. 執(zhí)行用時:1 ms 
  2. 內(nèi)存消耗:40.5 MB 

時間復(fù)雜度

該算法相當(dāng)于遍歷了兩遍鏈表,遞推一遍,歸檔一遍,所以一共為2n。

去除常量,時間復(fù)雜度就是O(n)

空間復(fù)雜度

由于用到ArrayList和數(shù)組,所以空間復(fù)雜度也是O(n)。

解法二

第二種解法就是利用棧的特點:先入后出。(棧的知識點后面再細(xì)說)

先入后出不就是題目的需求么,從尾部倒著輸出數(shù)字。

所以我們把鏈表依次入棧,然后在依次出棧就可以完成需求了。

  1. class Solution { 
  2.     public int[] reversePrint(ListNode head) { 
  3.         LinkedList<Integer> stack = new LinkedList<Integer>(); 
  4.         while(head != null) { 
  5.             stack.addLast(head.val); 
  6.             head = head.next
  7.         } 
  8.         int[] res = new int[stack.size()]; 
  9.         for(int i = 0; i < res.length; i++) 
  10.             res[i] = stack.removeLast(); 
  11.     return res; 
  12.     } 

方法消耗情況

  1. 執(zhí)行用時:1 ms 
  2. 內(nèi)存消耗:39.2 MB 

時間復(fù)雜度

同上一個算法一樣,時間復(fù)雜度就是入棧和出棧的時間,也就是O(n)。

空間復(fù)雜度

由于用到了stack和數(shù)組res,所以空間復(fù)雜度也是O(n)。

參考

https://leetcode-cn.com/problems/cong-wei-dao-tou-da-yin-lian-biao-lcof/

https://time.geekbang.org/column/article/41013

本文轉(zhuǎn)載自微信公眾號「碼上積木」,可以通過以下二維碼關(guān)注。轉(zhuǎn)載本文請聯(lián)系碼上積木公眾號。

 

責(zé)任編輯:武曉燕 來源: 碼上積木
相關(guān)推薦

2021-02-04 08:18:53

LeetCode鏈表

2021-01-28 08:20:41

鏈表空間復(fù)雜度

2021-02-03 13:23:42

鏈表倒數(shù)結(jié)點

2021-03-12 08:19:20

數(shù)組跳躍游戲

2021-01-22 08:30:50

LeetCode數(shù)字數(shù)組

2022-02-16 09:12:22

LeetCode升序鏈表鏈表數(shù)組

2021-03-22 08:23:29

LeetCode二叉樹節(jié)點

2022-01-17 09:23:02

LeetCode刪除鏈表算法

2021-03-02 08:21:58

LeetCode括號

2021-01-15 08:19:26

二維數(shù)組LeetCode

2021-03-17 08:19:22

二叉樹LeetCode

2021-04-12 15:47:00

數(shù)據(jù)結(jié)構(gòu)算法鏈表

2021-12-01 09:00:57

LeetCode回文數(shù)字算法

2021-12-31 09:01:44

LeetCode 羅馬數(shù)字四數(shù)之和

2021-07-15 06:43:12

Python數(shù)據(jù)結(jié)構(gòu)

2017-03-01 13:58:46

Python數(shù)據(jù)結(jié)構(gòu)鏈表

2021-07-13 07:52:03

Python數(shù)據(jù)結(jié)構(gòu)

2021-10-29 11:27:52

鏈表數(shù)據(jù)結(jié)構(gòu)算法

2022-02-11 09:42:21

Swift開發(fā)語言LeetCode

2022-10-12 09:01:11

動態(tài)規(guī)劃算法題
點贊
收藏

51CTO技術(shù)棧公眾號