算法---遞歸

遞歸結題三部曲

何為遞歸?程序反復調用自身即是遞歸。

我自己在剛開始解決遞歸問題的時候,總是會去糾結這一層函數做了什么,它調用自身后的下一層函數又做了什么…然后就會覺得實現一個遞歸解法十分復雜,根本就無從下手。

相信很多初學者和我一樣,這是一個思維誤區,一定要走出來。既然遞歸是一個反復調用自身的過程,這就說明它每一級的功能都是一樣的,因此我們只需要關注一級遞歸的解決過程即可。
在這里插入圖片描述
從圖中可以看出,遞歸是先遞后歸,自下往上處理。

如上圖所示,我們需要關心的主要是以下三點:

  1. 整個遞歸的終止條件。
  2. 一級遞歸需要做什么?
  3. 應該返回給上一級的返回值是什么?

因此,也就有了我們解樹形遞歸的三部曲 :

  1. 找到整個遞歸的終止條件:遞歸應該在什么時候結束?
  2. 找返回值:本級應該給上一級返回什么信息?
  3. 本級遞歸應該做什么:在這一級遞歸中,應該完成什么任務?

定要理解這3步,這就是以后遞歸秒殺算法題的依據和思路。

但這么說好像很空,我們來以題目作為例子,看看怎么套這個模版,相信5道題下來,你就能慢慢理解這個模版。之后再解這種套路遞歸題都能直接秒了

例1:求二叉樹的最大深度

先看一道簡單的LEEDCode題目:104. 二叉樹的最大深度

直接套遞歸結題三部曲:

  1. 找終止條件:什么情況下不在遞歸下去?當然是樹為空的時候,此時樹的深度為0,遞歸就結束了。
  2. 找返回值:本級應該返回給上一級什么信息?題目是要我們求最大深度,我們需要返回的當然是當前級對應的樹的最大深度,比如下圖的右邊,返回值應該是root的最大深度,root的下一級有l和r
  3. 本級應該做什么:首先,還是強調要走出之前的思維誤區,遞歸后我們眼里的樹一定是下圖右邊。此時就三個節點:root、root.left、root.right,根據第二步,root.left和root.right分別記錄的是root的左右子樹的最大深度,那么本級遞歸應該做的就很明確了,那就是在root的左右子樹中選擇一個較大的一個,加上1就是root的最大深度了,然后再返回這個深度即可
    在這里插入圖片描述
int maxDepth(struct TreeNode* root){if(root==NULL){return 0;}/* root的左右子樹最大高度 */int leftDepth = maxDepth(root->left);int rightDepth = maxDepth(root->right);/* 返回值是左右子樹最大深度加1 */return leftDepth>rightDepth?(leftDepth+1):(rightDepth+1);
}

例2 :兩兩交換鏈表中的結點。

看了一道遞歸套路解決二叉樹的問題后,有點套路搞定遞歸的感覺了嗎?我們再來看一道Leetcode中等難度的鏈表的問題,掌握套路后這種中等難度的問題真的就是秒:Leetcode 24. 兩兩交換鏈表中的節點

三部曲模板:

  1. 找終止條件:什么情況下終止?沒有辦法交換的時候,遞歸就停止。因此當鏈表只剩一個結點或者沒有幾點的時候,自然遞歸就終止了。
  2. 找返回值:本級希望向上一級返回的信息是什么?由于我們的目的是兩兩交換鏈表中相鄰的結點,因此自然希望交換給上一級遞歸的是本級已經處理好的鏈表。
  3. 本級應該做什么?題目讓交換相鄰兩個節點,所以我們應該交換相鄰兩個節點,涉及三個結點,兩個指針,head結點,head->next結點,以及head->next->next后面已經處理好的鏈表,我們看做一個結點。本級遞歸的任務就是交換這3個結點中的前兩個結點。

在這里插入圖片描述

struct ListNode* swapPairs(struct ListNode* head) {/* 終止條件 */if (head == NULL || head->next == NULL) {return head;}/* 獲取head->next結點 */struct ListNode*next = head->next;/* swapPairs(next->next)代表已經處理好的鏈表,交換兩個節點,我們要讓head指向這個結點 */head->next = swapPairs(next->next);/* next指向head結點 此時next就是該鏈表的頭結點*/next->next = head;/* 返回本級處理好的鏈表 */return next;
}

例3:平衡二叉樹

相信經過以上2道題,你已經大概理解了這個模版的解題流程了。

那么請你先不看以下部分,嘗試解決一下這道easy難度的Leetcode題(個人覺得此題比上面的medium難度要難):Leetcode 110. 平衡二叉樹

我覺得這個題真的是集合了模版的精髓所在,下面套三部曲模版:

  1. 終止條件:什么情況下終止?自然是子樹為空的時候,空樹是平衡二叉樹。
  2. 返回值:為什么我說這個題是集合了模版精髓?正是因為此題的返回值。要知道我們搞這么多花里胡哨的,都是為了能寫出正確的遞歸函數,因此在解這個題的時候,我們就需要思考,我們到底希望返回什么值?何為平衡二叉樹?平衡二叉樹即左右兩棵子樹高度差不大于1的二叉樹。而對于一顆樹,它是一個平衡二叉樹需要滿足三個條件:它的左子樹是平衡二叉樹,它的右子樹是平衡二叉樹,它的左右子樹的高度差不大于1。換句話說:如果它的左子樹或右子樹不是平衡二叉樹,或者它的左右子樹高度差大于1,那么它就不是平衡二叉樹。兩個條件才能判斷是不是平衡二叉樹。
    而在我們眼里,這顆二叉樹就3個節點:root、left、right。那么我們應該返回什么呢?如果返回一個當前樹是否是平衡二叉樹的boolean類型的值,那么我只知道left和right這兩棵樹是否是平衡二叉樹,無法得出left和right的高度差是否不大于1,自然也就無法得出root這棵樹是否是平衡二叉樹了。而如果我返回的是一個平衡二叉樹的高度的int類型的值,那么我就只知道兩棵樹的高度,但無法知道這兩棵樹是不是平衡二叉樹,自然也就沒法判斷root這棵樹是不是平衡二叉樹了。
    因此,我們定義一個結構體,該結構體包含結點的深度,以及該節點是不是平衡二叉樹。
struct inf{int length;//當前節點的長度bool isB;  //當前節點是不是平衡樹};

返回值就是當級節點的深度以及該節點是不是平衡二叉樹。如果不是平衡二叉樹,返回值的深度為0

  1. 本級遞歸該做什么?知道了第二步的返回值后,我們應該先獲得當前節點左右子樹的struct inf信息,即左右子樹的深度以及是不是平衡二叉樹。然后判斷左右子樹是不是平衡二叉樹以及高度差是否大于1。
struct inf{int length;//當前節點的長度bool isB;  //當前節點是不是平衡樹};
struct inf *tru ;   /* 表示一個節點的初始狀態是平衡二叉樹 */
struct inf *fal ;   /* 表示不是平衡二叉樹 */struct inf *getInf(struct TreeNode *root)
{if(root==NULL){return tru; }/* 獲取左右子樹的深度以及是不是平衡二叉樹信息 */struct inf *right = getInf(root->right);struct inf *left  = getInf(root->left);/*判斷左右子樹是不是平衡二叉樹*/if(right->isB == false || left->isB == false ){return fal;}/* 高度差是否大于1 */if(abs(right->length-left->length)>1){return fal;}/* 返回值左右子樹深度最大值加1并且是平衡二叉樹 */struct inf *ret = (struct inf *)malloc(sizeof(struct inf));ret->length = fmax(left->length,right->length)+1;ret->isB = true;return ret;}bool isBalanced(struct TreeNode* root){tru = (struct inf *)malloc(sizeof(struct inf));tru->length=0;tru->isB=true;fal = (struct inf *)malloc(sizeof(struct inf));fal->length=0;fal->isB = false;struct inf *ret = getInf(root);if(ret->isB==true)return true;elsereturn false;
}

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/379597.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/379597.shtml
英文地址,請注明出處:http://en.pswp.cn/news/379597.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

給定條件找最小值c語言程序_根據給定條件最小化n的最小步驟

給定條件找最小值c語言程序Problem statement: 問題陳述: Given a number n, count minimum steps to minimize it to 1 performing the following operations: 給定數字n ,執行以下操作,計算最少的步驟以將其最小化為1: Operat…

提高C#編程水平不可不讀的50個要訣

提高C#編程水平的50個要點 1.總是用屬性 (Property) 來代替可訪問的數據成員 2.在 readonly 和 const 之間,優先使用 readonly 3.在 as 和 強制類型轉換之間,優先使用 as 操作符 4.使用條件屬性 (Conditional Attributes) 來代替條件編譯語句 #if 5.總是…

那個年代的蘇聯歌曲

小時候,不時聽父親提起電影《這里的黎明靜悄悄》,怎么也想不到如此美麗的名字為什么要和戰爭聯系起來。后來在大學看了這部電影之后,開始認為這名字是合適的,因為電影講的是女性——戰場中的女性,各自都懷揣著愛情去保…

linux系統編程---進程總結

進程控制總結1 進程創建的三種方式forkvfrokclone2 進程終止進程正常退出returnexit_exit進程異常退出進程收到某個信號,而該信號使進程終止abort3 進程等待進程等待的方法waitwaitpid4 進程替換替換原理替換函數制作一個簡單的shell1 進程創建的三種方式 參考文章…

銀行賬務轉賬系統(事務處理)

流程如下: 創建項目工程如下: transfer包下的代碼如下: package beyond.transfer.dao;import java.sql.Connection; import java.sql.SQLException;import org.apache.commons.dbutils.QueryRunner;import beyond.utils.DataSourceUtils;pu…

【msdn wpf forum翻譯】TextBox中文本 中對齊 的方法

原文鏈接:http://social.msdn.microsoft.com/Forums/en-US/wpf/thread/49864e35-1dbf-4292-a361-93f1a8400558問題:TextBox中文本中對齊,使用 TextBox.HorizontalContentAlignment"Center"行不通(TextBox.VerticalConte…

wifi操作及實例

1.什么事WIFI 利用無線路由器上網的協議2.獲取WIFI網卡的狀態 WIFI網卡的狀態是由一系列的整形常量來表示的 有狀態: 網卡不可用WIFI_STATE_DISABLED 對應值為1 網卡正在關閉WIFI_STATE_DISABLING 對應值為0 網卡可用WIFI_STATE_ENABLED 對應的值為3 …

c語言 函數的參數傳遞示例_C語言中帶有示例的remove()函數

c語言 函數的參數傳遞示例C語言中的remove()函數 (remove() function in C) The remove() function is defined in the <stdio.h> header file. remove()函數在<stdio.h>頭文件中定義。 Prototype: 原型&#xff1a; int remove(const char* filename);Parameter…

使用ThreadLocal綁定連接資源(事務)

dao層代碼如下&#xff1a; package beyond.transfer.dao;import java.sql.Connection; import java.sql.SQLException;import org.apache.commons.dbutils.QueryRunner;import beyond.utils.DataSourceUtils; import beyond.utils.MyDataSourceUtils;public class TransferDa…

算法---棧和隊列

棧和隊列1 棧棧的順序存儲棧的鏈式存儲2 隊列隊列的順序存儲隊列的鏈式存儲3 棧和隊列的應用用棧實現隊列用隊列實現棧最小棧1 棧 參考文章&#xff1a; https://zhuanlan.zhihu.com/p/346164833 https://zhuanlan.zhihu.com/p/120965372#:~:text%E6%A0%88%E6%98%AF%E4%B8%80%…

學習網站LIST

面向對象的腳本語言Rubyhttp://rubycn.ce-lab.net/20020101.htmlRUBY文檔中心http://www.moer.net/ruby/doc/TCL腳本http://www.tclchina.com/Python快速入門http://wiki.woodpecker.org.cn/moin/WeiZhong/2006-01-17Python 研究(Dive Into Python)http://www.woodpecker.org.c…

再次參加(第七屆)商學院徒步戈壁挑戰賽,賦詞幾首

2012年5月21-25日&#xff0c;再次踏上甘肅莫賀延磧戈壁&#xff0c;參加第七屆商學院徒步戈壁挑戰賽。時隔五年&#xff0c;時空轉換。 少年游 ——戈壁緣 江南物華&#xff0c;遠水碧山&#xff0c;燈火相掩映。暮宴朝歡&#xff0c;酒綠燈紅&#xff0c;躑躅夜歸人。 孤城落…

Java StackTraceElement toString()方法與示例

StackTraceElement類的toString()方法 (StackTraceElement Class toString() method) toString() method is available in java.lang package. toString()方法在java.lang包中可用。 toString() method is used to represent stack trace element as a string or in other word…

增刪改查

web層代碼如下&#xff1a; package beyondwsq.web;import java.io.IOException; import java.sql.SQLException; import java.util.List;import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; imp…

在WebBrowser中通過模擬鍵盤鼠標操控網頁中的文件上傳控件

引言 這兩天沉迷了Google SketchUp&#xff0c;剛剛玩夠&#xff0c;一時興起&#xff0c;研究了一下WebBrowser。 我在《WebBrowser控件使用技巧分享》一文中曾談到過“我現在可以通過WebBrowser實現對各種Html元素的操控&#xff0c;唯獨無法控制Html的上傳控件”&#xff0c…

編寫最簡單的字符設備驅動

編寫最簡單的字符設備驅動1 編寫驅動代碼2 編寫makefile3 編譯和加載驅動4 編寫應用程序測試驅動參考文章&#xff1a; linux驅動開發第1講&#xff1a;帶你編寫一個最簡單的字符設備驅動 linux驅動開發第2講&#xff1a;應用層的write如何調用到驅動中的write 1 編寫驅動代碼…

Java ObjectStreamField toString()方法與示例

ObjectStreamField類toString()方法 (ObjectStreamField Class toString() method) toString() method is available in java.io package. toString()方法在java.io包中可用。 toString() method is used to return a string that defines this field. toString()方法用于返回定…

linux內核文件描述符fd、文件索引節點inode、文件對象file關系

文件描述符fd、文件索引節點inode、文件對象file關系1 VFS對象1.1 超級塊對象1.2 索引節點對象1.3 文件對象1.4 進程描述符1.5 files_struct2 如何根據文件描述符fd找到文件&#xff1f;1 VFS對象 在說fd、inode和file關系之前&#xff0c;我們先了解VFS的幾個概念。分別是進程…

sql2005 獲取表字段信息和視圖字段信息

獲取表字段名,和字段說明SELECT[Table Name]OBJECT_NAME(c.object_id), [ColumnName]c.name, [Description]ex.value FROMsys.columns c LEFTOUTERJOINsys.exte…

解析css之position

CSS的很多其他屬性大多容易理解&#xff0c;比如字體&#xff0c;文本&#xff0c;背景等。有些CSS書籍也會對這些簡單的屬性進行大張旗鼓的介紹&#xff0c;而偏偏忽略了對一些難纏的屬性講解&#xff0c;有避重就輕的嫌疑。CSS中主要難以理解的屬性包括盒型結構&#xff0c;以…