斐波那契額數列


傳統的遞歸實現

public long fibonacci(int n) {
	if (n <= 0) {
		return 0;
	}
	if (n == 1) {
		return 1;
	}
	return fibonacci(n - 1) + fibonacci(n - 2);
}

但以遞歸求解的過程中會出現很多重復求解 如圖:

思路

優化方法:

  1. 把已得到的數列保存起來,下次計算時先查詢,已計算過就不用重復計算.
  2. 采用從下往上計算,可以把計算過了的保存起來,下次要計算時就不必重復計算了:先由f(0)和f(1)計算f(2),再由f(1)和f(2)計算f(3)……以此類推就行了,計算第n個時,只要保存第n-1和第n-2項就可以了。

實現

public long fibonacci(int n) {
	int result[] = {0, 1};
	if (n < 2) {
		return result[n];
	}
	long fibNMinusOne = 1;
	long fibNMinusTwo = 0;
	long fibN = 0;
	for (int i = 2; i <= n; i++) {
		fibN = fibNMinusOne + fibNMinusTwo;
		fibNMinusTwo = fibNMinusOne;
		fibNMinusOne = fibN;
	}
	return fibN;
}

變種I

一只青蛙一次可以跳上1級台階,也可以跳上2級。求該青蛙跳上一個n級的台階總共有多少種跳法。

思路

將跳法總數記為f(n),可以知道f(1)=1,f(2)=2。當n>2時,第一次跳1級的話,還有f(n-1)種跳法;第一次跳2級的話,還有f(n-2)種跳法,所以可以推得f(n)=f(n-1)+f(n-2).

實現

public int JumpFloorI(int n) {
	if (n ==2) {
		return 2;
	}
	if (n == 1) {
		return 1;
	}
	return JumpFloorI(n - 1) + JumpFloorI(n - 2);
}

變種II

一只青蛙一次可以跳上1級台階,也可以跳上2級……它也可以跳上n級。求該青蛙跳上一個n級的台階總共有多少種跳法。

思路

n級台階,第一步有n種跳法:跳1級、跳2級、到跳n級
跳1級,剩下n-1級,則剩下跳法是f(n-1)
跳2級,剩下n-2級,則剩下跳法是f(n-2)
所以f(n)=f(n-1)+f(n-2)+...+f(1)
因為f(n-1)=f(n-2)+f(n-3)+...+f(1)
兩個相減f(n)-f(n-1)=f(n-1)
所以f(n)=2*f(n-1)

實現

public int JumpFloorII(int n) {
	if (n == 1) {
		return 1;
	} else {
		return 2 * JumpFloorII((n - 1));
	}
}

變種III

我們可以用21的小矩形橫着或者豎着去覆蓋更大的矩形。
請問用n個2
1的小矩形無重疊地覆蓋一個2*n的大矩形,總共有多少種方法?

思路

  1. target= 1大矩形為2*1,只有一種擺放方法,return1;
  2. target= 2 大矩形為2*2,有兩種擺放方法,return2;
  3. target= n時候第一次擺放有兩種方式

因為,擺放了一塊12的小矩陣,對應下方的12,擺放方法就確定了,所以為f(targte-2)

此解來自牛客網Follow

實現

public int RectCover(int target) {
	if (target < 1) {
		return 0;
	}
	if (target == 1) {
		return 1;
	}
	if (target == 2) {
		return 2;
	}
	return RectCover(target - 1) + RectCover(target - 2);
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM