《算法筆記》總結No.5——遞歸

一.分而治之

將原問題劃分為若干個規模較小而結構與原問題相同或相似的子問題,然后分別解決這些子問題,最后合并子問題的解,即可得到原問題的解,步驟抽象如下:

  1. 分解:將原問題分解為若干子問題
  2. 解決:遞歸求解所有子問題,如果子問題的規模小到可以直接解決,就直接解決它
  3. 合并:將子問題的解合并為原問題的解

子問題之間應該是相互獨立且沒有交叉的,從嚴格的定義上將,子問題個數為1的情況稱為減治,而大于1的情況稱為分治。

分治法作為一種思想,即可使用遞歸的手段去實現,也可以通過非遞歸的手段去實現。

二.遞歸

遞歸的一個很符合精髓且搞笑的定義:要理解遞歸,你要先理解遞歸,直到你能理解遞歸為止

遞歸的核心在于——反復調用自身函數,但是每次能把問題范圍縮小,直到范圍縮小到可以直接得到邊界數據的結果,然后再在返回的路上求出對應的解。

兩個重要概念:

  • 遞歸邊界:分解問題的盡頭
  • 遞歸式(或者稱之為遞歸調用、遞歸函數):分解子問題的手段

????????如果使用遞歸而式而不進行阻止,那么最后將會無法停止這個黑洞似的無窮盡的算法。遞歸的代碼結構中移動存在上述兩個概念,他們支撐起了整個遞歸最關鍵的邏輯。

三.遞歸計算階乘

直接先上代碼:

#include <iostream>
using namespace std;int F(int n){if(n==0) return 1;elsereturn F(n-1)*n;
}int main() {int n=0;cin>>n;cout<<F(n);return 0; 
}

仔細觀察,不難發現:

  • 遞歸邊界:n==0
  • 遞歸式:F(n-1)*n

來仔細的分析一下,對于F(5)來說——相當于是F(4)*5,以此類推,直接將F(5)分解到了F(0),此時F(0)=1,即子問題的答案,再將所有子問題的答案合并,即可完成本次求解~

假設輸入的是3,則推倒過程依次為:

  • F(3)
  • F(2)*3
  • F(1)*2*3
  • F(0)*1*2*3
  • 得到最后的F(0)的值以后,再返回去依次計算F(1)、F(2)、F(3)

四.遞歸計算裴波那契數列

#include <iostream>
using namespace std;int F(int n){if(n==0||n==1) return 1;elsereturn F(n-1)+F(n-2);
}int main() {int n=0;cin>>n;cout<<F(n);return 0; 
}

仔細觀察,也沒什么難度:

  • 遞歸邊界:0和1的返回值均為1
  • 遞歸式:根據定義,第三項開始即為前兩項的和

????????對于這類遞歸問題,只要找到了遞歸邊界和遞歸式,寫起來代碼就沒什么難度。遞歸邊界用來返回最簡單底層的結果,遞歸式用來減小規模并進一步向下一層遞歸。遞歸圖可以將遞歸放在一個平面上思考,有利于更快分析題目~

五.全排列

????????某種意義上來說,學會遞歸的思維正是從一個只會暴力的小白蛻變的過程,比如當我們要求輸入1~n之間數的全排列,如果硬碰硬直接霸王硬上弓,這個復雜度簡直不能想象——畢竟光數量都達到n的階乘個,何況找起來也是很費事的。

? ? ? ? 從遞歸的角度去考慮,如果把問題描述成“1~n這n個整數的全排列”,那么就可以拆分為若干個子問題:“輸出以1開頭的全排列”、“輸出以2開頭的全排列”……以此類推。不妨設置一個數組P,用來存放當前的排列;再設置一個散列數組hashTable,其中hashTable[x]當x已在P中時賦值為true。

? ? ? ? 現在按照順序往P中的第1位到第N位填入數字。不妨假設當前已經填好了1~index-1位,正準備去填寫index位。我們需要枚舉1~n,如果當前枚舉的數字x還沒喲再1~index-1中,即填入到index位,同時設置hashTable[x]為true,然后去處理index+1位;如果遞歸完成時,以便讓P[index]填寫下一個數字。

#include <cstdio>
#include <iostream> 
using namespace std;
const int maxn=11;int n,P[11],hashTable[maxn]={false};
//p為當前排列
//hashTable用來記錄x是否已經在P中! void generateP(int index)  //當前處理的正是第index位 
{if(index==n+1) //1~n已經處理完了,所以相當于n+1為遞歸邊界~ {for(int i=1;i<=n;i++)cout<<P[i];  //輸出當前排列 cout<<endl;return;}for(int x=1;x<=n;x++)   //枚舉1~n,試圖將x填入到P[index]位上! {if(hashTable[x]==false)   //false即表示不存在~ {P[index]=x;   //填入到index位 hashTable[x]=true;  generateP(index+1);  //遞歸處理下一位:即index+1 hashTable[x]=false;}}
}int main() {n=3;generateP(1);return 0; 
}
  • 遞歸邊界:index==n+1
  • 遞歸式:generateP(index+1);

六.N皇后問題

????????N 皇后問題指的是如何將 N 個皇后放置在 N × N 的棋盤上,并且使皇后彼此之間不能相互攻擊。即給你一個整數 N ,返回所有不同的 N?皇后問題的解決方案數量~

????????這玩意,不知道大家有沒有想起來行列式的定義:將行列式視為從矩陣的不同行和不同列中選取元素并相乘的代數和。每一項的符號由列標的逆序數決定,即如果列標的逆序數為奇數,則該項為負;若為偶數,則該項為正——其實就是全排列~不過不同的是,行列式可以在對角線上選擇元素,而對于可以斜線行走的皇后,這一點顯然也是不行。因此可以基于全排列的代碼,然后對每一個全排列的結果進行單獨判斷是否存在對角線元素,即可完成~?

?如下:判斷是否在同一對角線,只需要看行距之差和列距之差的絕對值是否相同,即可:

int count=0;
void generateP(int index)  //當前處理的正是第index位 
{if(index==n+1) //1~n已經處理完了,所以相當于n+1為遞歸邊界~ {bool flag=true;  //flag為true時表示當前為一個合法方案~ for(int i=1;i<=n;i++){for(int j=1;j<=n;j++)if(abs(i-j)==abs(P[i]-P[j])) flag=false;   //不合法 	}if(flag)count++;return;}for(int x=1;x<=n;x++)   //枚舉1~n,試圖將x填入到P[index]位上! {if(hashTable[x]==false)   //false即表示不存在~ {P[index]=x;   //填入到index位 hashTable[x]=true;  generateP(index+1);  //遞歸處理下一位:即index+1 hashTable[x]=false;}}
}

對于遞歸,只要想清楚邊界、遞歸式、問題需要的答案,就沒什么難度~

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

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

相關文章

用VLM訓練實時計算機視覺模型

經過數十億個參數訓練的 AI 模型非常強大&#xff0c;但并不總是適合實時使用。但是&#xff0c;它們可以通過自動監督快速專用模型的標注來減少人力投入。 ? 如果你曾經構建過計算機視覺模型&#xff0c;就就會知道監督需要大量工作——人類花時間&#xff08;數小時或數天&a…

自動化測試全攻略:從入門到精通!

1、自動化測試專欄 隨著技術的發展和工作需求的增長&#xff0c;自動化測試已成為軟件質量保障體系中不可或缺的一環。 為了幫助廣大測試工程師、開發者和對自動化測試感興趣的讀者們更好地掌握這一技能&#xff0c;今年特別推出了全新的《自動化測試全攻略&#xff1a;從入門…

scratch繪制四個三角形 2024年6月中國電子學會 圖形化編程 scratch編程等級考試二級真題和答案解析

scratch繪制四個三角形 一、題目要求 2024年6月電子學會圖形化編程Scratch等級考試二級真題 1、準備工作 1.保留默認角色小貓; 2.添加背景Stars。 2、功能實現 1 .隱藏角色小貓&#xff0c;設置畫筆裙始位置為(0,0)&#xff0c;畫筆顏色為黃色&#xff0c;畫筆的粗細為5…

Scala Trait(特征)

Scala Trait(特征) Scala中的Trait是一種特殊的概念,它類似于Java中的接口,但提供了更多的功能。Trait允許我們定義一組方法,這些方法可以被子類實現,同時還可以包含方法的實現。這使得Trait既具有接口的靈活性,又具有抽象類的實用性。在本文中,我們將深入探討Scala Tra…

NET Core 中的空對象設計模式

介紹 一種稱為“空對象模式”的行為設計模式提供了一個對象來表示接口缺少的對象。在空對象會導致空引用異常的情況下&#xff0c;這是一種提供替代行為的方法。在本文中&#xff0c;我們將深入探討 C# 空對象模式&#xff0c;并逐步解決更復雜的情況。 空對象設計模式它是什…

k8s離線部署芋道源碼前端

目錄 概述 編譯Dockerfile 構建Dockerfilenginx.conf構建 k8s部署前端鏡像部署ingress 概述 本篇將對 k8s離線部署芋道源碼前端 進行詳細的說明&#xff0c;對如何構建 Dockerfile&#xff0c;如何整合 Nginx&#xff0c;如何整合 ingress 進行實踐。 相關文章&#xff1a;naco…

python 進階教程--PIL圖像處理

PIL圖像處理 1. Pillow庫簡介2. 圖像處理基礎3. 圖像操作4. 圖像增強5. 圖像處理進階6. 圖像繪制7. 圖像序列和動畫8. 圖像識別和特征提取9. 實戰項目10. 常見問題解答 1. Pillow庫簡介 PIL與Pillow的關系 PIL&#xff08;Python Imaging Library&#xff09;是一個提供圖像處…

【云原生之kubernetes實戰】在k8s環境下部署OrangeHRM人力資源管理系統

【云原生之kubernetes實戰】在k8s環境下部署OrangeHRM人力資源管理系統 一、OrangeHRM介紹1.1 OrangeHRM 簡介1.2 OrangeHRM特點1.3 OrangeHRM使用場景二、相關知識介紹2.1 本次實踐存儲介紹2.2 k8s存儲介紹三、本次實踐介紹3.1 本次實踐簡介3.2 本次環境規劃3.3 部署前需準備工…

bash終端快捷鍵

快捷鍵作用ShiftCtrlC復制ShiftCtrlV粘貼CtrlAltT新建終端ShiftPgUp/PgDn終端上下翻頁滾動CtrlC終止命令CtrlD關閉終端CtrlA光標移動到最開始為止CtrlE光標移動到最末尾CtrlK刪除此處到末尾的所有內容CtrlU刪除此處至開始的所有內容CtrlD刪除當前字符CtrlH刪除當前字符的前一個…

Perl 語言開發(十):正則表達式,掌握強大文本處理的利器

目錄 1. 正則表達式概述 2. 基礎正則表達式語法 2.1 字符和字符類 2.2 預定義字符類 2.3 量詞 2.4 分組和捕獲 2.5 反向引用 3. Perl 中的正則表達式操作 3.1 匹配操作 3.2 替換操作 3.3 分割操作 4. 正則表達式的高級特性 4.1 非捕獲分組 4.2 前瞻和后顧 4.3 負…

Hugging face Transformers(4)—— Model

Hugging Face 是一家在 NLP 和 AI 領域具有重要影響力的科技公司&#xff0c;他們的開源工具和社區建設為NLP研究和開發提供了強大的支持。它們擁有當前最活躍、最受關注、影響力最大的 NLP 社區&#xff0c;最新最強的 NLP 模型大多在這里發布和開源。該社區也提供了豐富的教程…

【Bug優化】支付寶支付中“交易訂單處理失敗,請稍后再試”問題

引言 近期&#xff0c;一位友友問&#xff1a;他在集成支付寶支付功能時遇到了一個棘手的問題&#xff0c;當用戶在支付過程中選擇放棄支付&#xff0c;嘗試重新支付同一訂單時&#xff0c;前端會顯示“交易訂單處理失敗&#xff0c;請稍后再試”。 這個問題的核心在于支…

文章SameStr(一):圖1代碼

“Publication Figure 1” 百度云盤鏈接: https://pan.baidu.com/s/15g7caZp354zIWktpnWzWhQ 提取碼: 4sh7 Libraries Standard Import library(tidyverse) library(cowplot) library(scales) library(ggpubr)Special # devtools::install_github("pmartinezarbizu/…

linux 代理export

export http_proxyhttp://10.67.11.138:7890 export https_proxyhttp://10.67.11.138:7890

大/小端模式與位操作

文章目錄 1. 大小端模式 2. 大端模式&#xff08;Big-endian&#xff09; 3. 小端模式&#xff08;Little Endian&#xff09; 4. 判斷和轉換大小端模式 5. 位操作 5.1 移位操作 5.2 取反操作 5.3 位與操作 5.4 位或操作 5.5 置位操作 5.6 清位操作 1. 大小端模式 …

大數據學習之 scala基礎(補充)

scala基礎&#xff1a; hello world: 寫scala可運行文件的注意事項1、如果一個scala文件要運行&#xff0c;class要改成object2、如果是class&#xff0c;就僅單純代表一個類&#xff0c;如果是object代表的是單例對象3、scala語法中&#xff0c;一句話結束不需要加分號4、sca…

Spring的AOP基礎以及AOP的核心概念

2. AOP基礎 學習完spring的事務管理之后&#xff0c;接下來我們進入到AOP的學習。 AOP也是spring框架的第二大核心&#xff0c;我們先來學習AOP的基礎。 在AOP基礎這個階段&#xff0c;我們首先介紹一下什么是AOP&#xff0c;再通過一個快速入門程序&#xff0c;讓大家快速體…

Ubuntu配置GitHub(第一次clone/push)

文章目錄 1. 安裝Git&檢查連接2. 注冊GitHub3. 生成&GitHub添加SSH3.1. 檢查&刪除已有id_rsa3.2. 生成SSH3.3. GitHub添加id_rsa.pub SSH3.4. 檢查SSH 4. 繼續開發可以參考參考 1. 安裝Git&檢查連接 安裝 sudo apt-get install git檢查SSH連接 ssh -T gitgi…

【工具分享】零零信安攻擊面管理平臺

文章目錄 00SEC-ASM?功能介紹功能演示 最近閑來無事&#xff0c;到處網上沖浪&#xff0c;無意間發現了長亭云圖攻擊面管理平臺&#xff0c;無奈需要授權才能使用&#xff0c;于是就找到了平替&#xff1a;零零信安攻擊面管理平臺。 長亭云圖攻擊面管理平臺&#xff1a;https:…

vue2封裝向上滾動組件

目錄 1.代碼2.使用 1.代碼 <template><div class"marquee-wrap" :style"{height: height px}"><ul class"marquee-list":style"animateUpStyle"v-on:mouseover"myMouseover"v-on:mouseout"myMouseout…