遞迴演算法 Java實現
阿新 • • 發佈:2019-01-30
緣起於網易的一道演算法筆試題,之前對遞迴演算法有一個初步印象。感覺遞迴好像就是一種迭代的過程。將原問題不斷分解為若干個與原問題類似更小的問題,直到小問題已知,也就是找到了遞迴演算法的出口,此時,再講問題迴帶得到解的結果。廢話不多說,先上題。
題目是這樣的:有一隻猴子第一天摘了很多桃,覺得很高興就立刻吃了桃總數的一半,然後覺得沒吃飽又吃了3個。猴子感覺這樣吃桃會立刻沒有,於是就定下一個規矩:每次在奇數天吃剩餘桃總數的一半再多加3個,每次在偶數天吃剩餘桃的總數的一半再多吃一個。請輸入一個天數,使得該天數的剩餘桃數正好為1,請打印出猴子第一天共摘了多少個桃?
問題分解:設輸入的天數為n;
首先,找到問題入口: 第1天時, 求剩餘桃數:F(1) ;
其次,找到問題的遞迴方程,在本題中,遞迴方程有兩個,
若n天為奇數天:有F(n) = (F(n+1)+3)*2
若n天為偶數天:有F(n) = (F(n+1)+1)*2
其中,奇數天與偶數天相互遞迴。
最後,問題結束:當程式求到第n天時,F(n) = 1 已知。
首先抽取遞迴式
很明顯遞迴式為,其中day變數用來存放你輸入的天數,用於遞迴結束的標誌。在遞迴中,先判斷遞迴完成後的結果,再寫入遞迴式。
private static int sumOddDay(int day, int count) { //奇數天的遞迴 if(count == day) return 1; else return 2*(sumEvenDay(day, count+1) + 3); }
private static int sumEvenDay(int day, int count) { //偶數天的遞迴
if(count == day) return 1;
else return 2*(sumOddDay(day,count+1) + 1);
}
補全天數是奇數還是偶數的判斷
private static int sumNum(int day, int count){ if(count%2 == 0){ return sumEvenDay(day, count); //偶數天數 }else { return sumOddDay(day, count); //奇數天數 } }
最終得到完整程式程式碼,如下
package Test;
import java.util.Scanner;
public class test {
public static void main(String [] args){
System.out.println("請輸入天數:");
Scanner scanner = new Scanner(System.in);
int day = scanner.nextInt(); //輸入值
System.out.println(sumNum(day,1));
}
private static int sumNum(int day, int count){
if(count%2 == 0){
return sumEvenDay(day, count); //偶數天數
}else {
return sumOddDay(day, count); //奇數天數
}
}
private static int sumOddDay(int day, int count) {
if(count == day) return 1;
else return 2*(sumEvenDay(day, count+1) + 3);
}
private static int sumEvenDay(int day, int count) {
if(count == day) return 1;
else return 2*(sumOddDay(day,count+1) + 1);
}
}
眾所周知,遞迴演算法的需要很大的記憶體空間,如果本題限制了執行記憶體,則遞迴演算法不太適用。於是,上網找了有關如何將遞迴演算法轉化成迴圈的方法,先總結如下。
1.使用棧
2.使用迴圈
大學課上講的最多的應該就是樹的遞迴演算法和非遞迴演算法的轉換了吧。樓主也不多說,網上或教科書上都有程式碼。