1. 程式人生 > >LeetCode70.爬樓梯(C++實現)

LeetCode70.爬樓梯(C++實現)

LeetCode70.爬樓梯的題目如下:

方法一:直接遞迴實現(超時)

剛開始直接用遞迴實現,思路也是比較直接的,如下圖,當n = 5的時候,有8種方法。

實現程式碼如下:

void selectStair(int remainStep, int &count)
{
	if(remainStep == 0)
	{ //當剩餘步數為0,說明找到一種方法,計數加一
		count++;
		return;
	}
	if(remainStep >= 2) //當剩餘臺階大於等於2時,有選擇餘地
	{
		selectStair(remainStep - 1, count);//走一階
		selectStair(remainStep - 2, count);//走兩階
	}else if(remainStep == 1){
		selectStair(remainStep - 1, count); //當剩餘臺階等於1,沒有選擇餘地,只能走一階
	}
}

//使用遞迴,超出時間限制
int climbStairs_recur(int n) {
	int count = 0, remainStep = n;
	selectStair(remainStep, count);
	return count;
}

但是這種遞迴實現的方法,當n很大的時候,遞迴的棧很深,耗時賊長,當n = 44的時候,就運行了很久才出來結果,在LeetCode上提交是超時的。很無奈,於是想了下面的辦法。

方法二:進階①——遞迴實現斐波那契數列(超時)

正苦於無奈,突然發現每個n對應的走法F(n)好像存在什麼規律,如下:

n   F(n)
1 -> 1
2 -> 2
3 -> 3
4 -> 5
5 -> 8
6 -> 13
7 -> 21
8 -> 34
9 -> 55
10 -> 89

看著似曾相識,咦~這不就是斐波那契數列嘛! F(n) = F(n - 1) + F(n - 2)

但是剛開始想斐波那契數列還是用遞迴實現,以為不用耗時太久,結果還是對遞迴的認識不夠深刻,上遞迴程式碼:

//規律-斐波那契數列-用遞迴實現(超時)
int F(int n)
{
	if(n == 1)
		return 1;
	if (n == 2)
		return 2;
	if(n > 2)
		return F(n - 1) + F(n - 2);
}

int climbStairs_F(int n) {
	return F(n);
}

結果發現,跟方法一也差不了多少。。。無奈!

幸好,實現斐波那契數列數列不一定非得用遞迴啊!咱用陣列照樣實現斐波那契數列。

方法三:進階②——陣列實現斐波那契數列(完美解決)

直接上程式碼:

//利用陣列實現斐波那契數列
int climbStairs(int n) {
	vector<int> s;
	s.push_back(1);
	s.push_back(2);//先把頭兩個元素放進陣列
	if (n == 1)
		return 1;
	if(n == 2)
		return 2;
	for (int i = 2; i < n; i++)
	{
		s.push_back(s[i - 1] + s[i - 2]); //用陣列儲存的方法去找F(n)
	}
	return s[n - 1];
}

最後的結果也是很棒的: