遞迴是數學上數學歸納法的模型。
不要陷入遞迴的具體細節。
遞迴思路,說白了是如下三步:
1、對於問題n,如果n-1已經解決了,那麼n是否很容易解決。
甲:想上天?你先給我找個天一樣高的梯子!舉例來說,如果要把乙個n層漢諾塔從a搬到c,那麼:乙:想要天一樣高的梯子?你先給我弄棵天一樣高的樹!
甲:想要天一樣高的樹?你先給我弄把能頂到天的鋸子!
……
如果前n-1層可以找別人搞定,咱只管搬第n層,會不會變得非常容易?
你看,這一下就簡單了:這時當它只有兩層就好了,先把前n-1層看作乙個整體,把它搬到b;然後把最下面的第n層搬到c;然後再把前n-1層從b搬到c。
類似的,假如接到「搬前n-1層」這個任務的是我們,怎麼搬呢?
簡單,像前東家一樣,把前n-2層外包出去,我們只搬第n-1層——其實和前面討論過的「外包n-1層,只搬第n層」完全一樣嘛。
依此類推,一層層「外包」下去——我不管你們有多傷腦筋,反正只要你們把我外包給你的活幹了,我就能幹了我的活!
注意,這裡千萬別管「接到外包工作的傢伙有多傷腦筋」——丟給他就讓他頭疼去,我們就別再撿回來痛苦自己了。這一步就是「遞推」。
注意這裡的搬法:搬第n層,就需要把前n-1層搬兩次,另外再把第n層搬一次;搬第n-1層,又需要把前n-2層搬兩次,然後再把n-1層搬一次,依此類推。2、一步步遞推下去,終究會有個「包工頭」,接到「搬第一層」的任務。很容易知道,一共需要搬2^n-1次。
第一層怎麼搬?
太簡單了,讓搬哪搬哪。
換句話說,到此,「遞推」就到了極限,簡單粗暴直接做就可以了。
3、既然第一層搬了,那麼第二層當然就可以搬了;第二層搬了,第三層又可以搬了……依次類推,直到第n層。於是問題搞定。
這一步就是「回歸」。
如上三步加起來,就是「遞迴」。
推而廣之,任何問題,不管規模為n時有多複雜,只要把n-1那塊「外包」給別人做之後,我們在這個基礎上可以輕易完成n,那麼它很可能就適合用「遞迴」解決。
那麼,怎麼最終確定它能不能用「遞迴」做呢?
看當n取1或2之類最簡情況時,問題是否可以解決——然後寫程式解決它。
容易看出,「遞迴」其實和「數學歸納法」的思路非常像:證明n=1時成立;證明若n=n-1成立,則n=n時也成立;如上兩步得證,則命題在n>1時一定成立(n為自然數)。
你看,我們沒必要從1開始逐一驗證每個自然數,只要證明了「基礎條件」、再證明了「遞推條件」,大自然的規律會幫我們搞定一切。
換句話說,只要我們:
1、寫程式告訴電腦「如何分解乙個問題」
2、寫程式告訴電腦「當該問題分解到最簡時如何處理」
那麼,「具體如何遞推、如何回歸」這個簡單問題就不要再操心了,電腦自己能搞定。
——寫出問題分解方法、寫出分解到最簡後如何解決,這是我們的任務;把問題搞定,是電腦的任務。這就是遞迴的魅力。
正是由於這種「我提供思路你搞定細節」的特點,「一切皆遞迴」的函式系語言才被稱為「宣告式程式設計」(而不是必須一步一步指導電腦如何做的「命令式程式設計」)。
這麼簡單輕鬆的事,非要自己吭哧吭哧一步步做出來——o(2^n)規模啊——難怪你們要陷入困境。
遞迴就是把複雜的問題分解,把規模大的問題,變成規模小的問題來解決。
乙個過程或函式在其定義或說明中有直接或間接呼叫自身的一種方法
用有限的語句來定義物件的無限集合;
通俗點來理解就是,我程式只有一套,但是我可以通過遞迴(自身呼叫自身)的特性,不管你有多少個值,我都能妥妥的給你按照特定的程式邏輯處理。
遞迴需要有邊界條件、遞迴前進段和遞迴返回段
當邊界條件不滿足時,遞迴前進;當邊界條件滿足時,遞迴返回
以下是另乙個可能更有利於理解遞迴過程的解釋:
我們已經完成了嗎?如果完成了,返回結果。如果沒有這樣的終止條件,遞迴將會永遠地繼續下去。
如果沒有,則簡化問題,解決較容易的問題,並將結果組裝成原始問題的解決辦法。然後返回該解決辦法。
漢諾塔問題的遞迴解決**:
把問題拆分為3步,首先把n-1的情況外包出去交給b作為快取(即假設已經完成,n-1怎麼完成請去找n-2,n-2請去找n-3,一直到1的時候,我們就知道怎麼做了),第二步就是把a上的移動到c上,第三步就是把快取區b移到c上,即完成漢諾塔。
漢諾塔由於有重複的操作,所以我們想到可以用遞迴來實現。
同樣,現在我們實現字串的全排列,比如 abc三個字元,它的全排列是3!種。
abc acb bac bca cab cba
乙個字元的全排列是它本身,比如字元a的全排列就是a本身。
考慮到我們可以先找出a,然後全排列bc,而bc全排列又可以分解,那麼遞迴是乙個不錯的方式。
遞迴 漢諾塔和字元排序問題
遞迴是數學上數學歸納法的模型。不要陷入遞迴的具體細節。遞迴當然只能以遞迴的思路理解,把它展開純屬自討苦吃。遞迴思路,說白了是如下三步 1 對於問題n,如果n 1已經解決了,那麼n是否很容易解決。甲 想上天?你先給我找個天一樣高的梯子!乙 想要天一樣高的梯子?你先給我弄棵天一樣高的樹!甲 想要天一樣高...
漢諾塔問題(遞迴)
題目描述 對於傳統的漢諾塔遊戲我們做乙個拓展,我們有從大到小放置的n個圓盤,開始時所有圓盤都放在左邊的柱子上,按照漢諾塔遊戲的要求我們要把所有的圓盤都移到右邊的柱子上,請實現乙個函式列印最優移動軌跡。給定乙個int n,表示有n個圓盤。請返回乙個string陣列,其中的元素依次為每次移動的描述。描述...
漢諾塔問題(遞迴)
問題 漢諾塔問題 解法 遞迴求解 思路 先把n 1從a移動b 在把第n個從a移到c 使用遞迴使得 變得簡單 複雜度 2的n次方 1 includeint step 1 void hanoi int level,char a,char b,char c 1 當盤子數大於1時,先把n 1個從a借助c移動...