成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

鏈表問題,如何優(yōu)雅遞龜嗎?

開發(fā) 前端
今天「小熊」主要介紹采用「遞歸」的策略,秒殺「鏈表」相關問題,使得代碼更「優(yōu)雅」,并以兩道常見的面試題作為例題來講解,供大家參考,希望對大家有所幫助。

 [[403833]]

本文轉載自微信公眾號「程序員小熊」,作者程序員小熊。轉載本文請聯系程序員小熊公眾號。

前言

大家好,我是來自華為的「程序員小熊」。相信絕大部分童鞋都知道,在處理與「鏈表」相關問題時,常用的解題套路主要包括「雙指針」、「迭代」和「虛擬頭節(jié)點」等等。

今天「小熊」主要介紹采用「遞歸」的策略,秒殺「鏈表」相關問題,使得代碼更「優(yōu)雅」,并以兩道常見的面試題作為例題來講解,供大家參考,希望對大家有所幫助。

鏈表與遞歸

鏈表具有天然的遞歸性,一個鏈表可以看出頭節(jié)點后面掛接一個更短的鏈表,這個更短的鏈表是以原鏈表的頭節(jié)點的下一節(jié)點為頭節(jié)點,依次內推,直到最后的更短的鏈表為空,空本身也是一個鏈表(最基礎的)。

以單鏈表 1->2->3->null 為例子,如下圖示:

原鏈表

將原鏈表看出頭節(jié)點 1 后掛接一個更短的鏈表

頭節(jié)點+更短鏈表

繼續(xù)拆解,直到無法拆解

更更短鏈表

更更更短鏈表

有了這樣的思考,很多「鏈表」相關問題,都可以采用「遞歸」的思路來解答。

劍指 Offer 24. 反轉鏈表

  1. 定義一個函數,輸入一個鏈表的頭節(jié)點,反轉該鏈表并輸出反轉后鏈表的頭節(jié)點。 
  2.   
  3.  
  4. 示例: 
  5.  
  6. 輸入: 1->2->3->4->5->NULL 
  7. 輸出: 5->4->3->2->1->NULL 
  8.   
  9.  
  10. 限制: 
  11. 0 <= 節(jié)點個數 <= 5000 

解題思路

要反轉鏈表,即將原鏈表的頭節(jié)點變?yōu)樾骆湵淼奈补?jié)點,原鏈表的尾節(jié)點變?yōu)樾骆湵淼念^節(jié)點。如下圖示:

反轉之前:

原鏈表

反轉之后:

新鏈表

主要策略主要有:1、直接修改鏈表的值,如上圖中的原鏈表圖所示,將原鏈表值 1 的頭節(jié)點改為原鏈表尾節(jié)點的值,依次類推;2、讓遍歷整個鏈表,讓鏈表的尾節(jié)點指向其前一個節(jié)點,依次類推。

雖然這兩個策略都可行,不過在面試中通常要求采用「策略2」。

由上面的「遞歸與鏈表」可知,本題也可以采用「遞歸法」去求解。

具體如何通過「遞歸」去解答呢?見下面例子。

「舉例」

鏈表 1->2->3->null 為例子,如下圖示。

示例

不斷遍歷找到原鏈表為尾節(jié)點,即新鏈表的頭節(jié)點。

原鏈表尾節(jié)點

然后讓尾節(jié)點指向其前驅節(jié)點,依次類推。

遞歸反轉

詳細步驟,如下動圖示:

遞歸反轉單鏈表

Show me the Code

「C」

  1. struct ListNode* reverseList(struct ListNode* head){ 
  2.     /* 遞歸終止條件 */ 
  3.     if (head == NULL || head->next == NULL) { 
  4.         return head; 
  5.     } 
  6.  
  7.     /* 反轉當前所在的鏈表節(jié)點 */ 
  8.     struct ListNode* newHead = reverseList(head->next); 
  9.  
  10.     /* 由原鏈表的尾節(jié)點挨個指向其前驅節(jié)點 */ 
  11.     head->next->next = head; 
  12.  
  13.     /* 防止成環(huán) */ 
  14.     head->next = NULL
  15.  
  16.     /* 返回新的鏈表頭節(jié)點 */ 
  17.     return newHead; 

「java」

  1. ListNode reverseList(ListNode head) { 
  2.     if (head == null || head.next == null) { 
  3.         return head; 
  4.     } 
  5.  
  6.     ListNode node = reverseList(head.next); 
  7.     head.next.next = head; 
  8.     head.next = null
  9.  
  10.     return node; 

當然本題也可以采用「迭代」的方法去做,其代碼(python 版)也很優(yōu)雅,具體如下:

Show me the Code

「python」

  1. def reverseList(self, head: ListNode) -> ListNode: 
  2.     cur, pre = head, None 
  3.     while cur: 
  4.         cur.next, pre, cur = pre, cur, cur.next 
  5.          
  6.     return pre  

「復雜度分析」

時間復雜度:「O(n)」,n 是鏈表的長度。對鏈表的每個節(jié)點都進行了反轉操作。

空間復雜度:「O(n)」,n 是鏈表的長度。遞歸調用的棧空間,最多為 n 層。

203. 移除鏈表元素

  1. 給你一個鏈表的頭節(jié)點 head 和一個整數 val ,請你刪除鏈表中所有滿足  
  2.  
  3. Node.val == val 的節(jié)點,并返回 新的頭節(jié)點 。 
  4.  
  5. 示例 1: 
  6.  
  7. 輸入:head = [1,2,6,3,4,5,6], val = 6 
  8. 輸出:[1,2,3,4,5] 
  9.  
  10. 示例 2: 
  11.  
  12. 輸入:head = [], val = 1 
  13. 輸出:[] 
  14.  
  15. 示例 3: 
  16.  
  17. 輸入:head = [7,7,7,7], val = 7 
  18. 輸出:[] 

解題思路

要移除鏈表中給定值的節(jié)點,一般策略是「找到給點值的節(jié)點的前驅節(jié)點,然后讓其指向給定值的節(jié)點的后繼節(jié)點」。

例如要刪除鏈表 1->2->3->null 中,節(jié)點值為 3 的節(jié)點,就得先找到其前驅節(jié)點(值為 2 的節(jié)點),如下圖示:

刪除給定值的節(jié)點

由上面的「遞歸與鏈表」可知,本題同樣也可以采用「遞歸法」去求解,不斷刪除更短鏈表中給定值的節(jié)點,然后再將處理后的更短的鏈表,掛接在其前驅節(jié)點后。

「注意」最后要判斷原鏈表的頭節(jié)點是否是待移除的節(jié)點。

「舉例」

以鏈表 1->2->3->null 為例子,移除鏈表中給定值的節(jié)點的過程,如下動圖示。

示例動圖

Show me the Code

「C++」

  1. ListNode* removeElements(ListNode* head, int val) { 
  2.     /* 遞歸終止條件 */ 
  3.     if(head == NULL) { 
  4.         return NULL
  5.     } 
  6.  
  7.     /* 刪除鏈表中頭節(jié)點后值為 val 的元素的節(jié)點 */ 
  8.     head->next=removeElements(head->next,val); 
  9.  
  10.     /* 判斷頭節(jié)點是否為值為 val 的節(jié)點,再返回*/ 
  11.     return head->val==val ? head->next : head; 

「Golang」

  1. func removeElements(head *ListNode, val int) *ListNode { 
  2.     if head == nil { 
  3.         return head 
  4.     } 
  5.  
  6.     head.Next = removeElements(head.Next, val) 
  7.     if head.Val == val { 
  8.         return head.Next 
  9.     } 
  10.  
  11.     return head 

「復雜度分析」

時間復雜度:「O(n)」,n 是鏈表的長度。遞歸需要遍歷鏈表一次。

空間復雜度:「O(n)」,n 是鏈表的長度。遞歸調用棧,最多不會超過 n 層。

 

責任編輯:武曉燕 來源: 程序員小熊
相關推薦

2021-04-19 07:41:37

AcceptEmfile問題

2022-08-11 11:09:38

線上問題程序員

2015-11-26 10:53:45

LinuxWindowsMac OS

2021-01-19 10:35:49

JVM場景函數

2022-09-28 12:23:36

Promise代碼

2017-07-26 11:32:50

NETRabbitMQ系統集成

2019-03-21 15:30:05

JavaStream性能

2021-03-24 10:20:50

Fonts前端代碼

2020-10-16 11:48:06

服務器系統運維

2023-10-10 13:23:18

空指針異常Java

2023-10-19 19:42:25

IstioPodkubernetes

2017-12-19 10:03:44

JavaLinux代碼

2020-08-26 07:17:19

通信

2022-09-09 15:17:02

CentOS 7Linux

2024-06-24 14:19:48

2025-06-24 08:25:00

Java并發(fā)編程線程

2021-11-15 06:56:45

系統運行空指針

2022-02-18 17:34:47

數組多維五維數組

2022-04-11 08:17:07

JVMJava進程

2023-06-28 08:25:14

事務SQL語句
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 亚洲国产成人精品女人久久久 | 国产精品一区二区福利视频 | 丁香婷婷成人 | 九九热精 | 国产在线精品免费 | 福利在线观看 | 久久久久久久久久久久一区二区 | 亚洲一本 | 精品视频99| 亚洲午夜精品视频 | 91精品在线看 | 一区二区播放 | 国产999精品久久久久久 | 韩国av影院 | 色网站入口 | 国产ts人妖系列高潮 | 国产传媒视频在线观看 | 久久久久久黄 | 免费三级av | 国产欧美久久一区二区三区 | 国外成人免费视频 | 国产精品a久久久久 | 嫩草视频入口 | 午夜小视频免费观看 | 欧美一级网站 | 成年视频在线观看福利资源 | 久久精品网 | 黄色日批视频 | 欧美精三区欧美精三区 | 一区在线观看 | 国产精品美女久久久久aⅴ国产馆 | 夜夜骚视频 | 日韩欧美亚洲 | 久久精品91 | 亚洲精品日日夜夜 | 日韩美女在线看免费观看 | 国产精品国产三级国产aⅴ中文 | 国产精品1区2区 | 在线免费观看黄色 | 欧美中文字幕一区二区 | 超级乱淫av片免费播放 |