原题
我们可以用 2*1
的小矩形横着或者竖着去覆盖更大的矩形。请问用 n 个 2*1
的小矩形无重叠地覆盖一个 2*n
的大矩形,总共有多少种方法?
My Answer
解题思路:
依旧是典型DP,只需要找出递归规律即可。
事实上,这个规律开始并没有一眼看出,对于这种情况,可以先尝试做出几个结果之后找规律,如 n=0
时,对应 res[0] = 0
,res[1] = 1
,res[2] = 2
,res[3] = 3
, res[4] = 5
,发现规律 res[n] = res[n-1] + res[n-2]
,完事利用回溯法实现:
# -*- coding:utf-8 -*-
class Solution:
def rectCover(self, number):
# write code here
if number == 0:
return 0
tempArray = [1,2]
if number >= 3:
for i in range(3,number+1):
tempArray[i] = tempArray[i-1] + tempArray[i-2]
return tempArray[number]
其实本题又是一道斐波那契数列的变形,上述方法的时间复杂度、空间复杂度均为O(n),可进一步优化空间复杂度。
优化版本:
class Solution {
public:
int rectCover(int number) {
int base1 = 1, base2 = 2, res;
if (number == 0){
return 0;
}
else if (number == 1){
return 1;
}
else if (number == 2){
return 2;
}
for(int i=3; i <= number; ++i){
res = base1 + base2;
base1 = base2;
base2 = res;
}
return res;
}
};
事实上,上述代码依旧有优化空间,可进一步降低变量及判定条件,即用temp_res
保存下一步的值,base
保存当前i对应结果,代码如下:
class Solution {
public:
int rectCover(int number) {
if (number == 0){
return 0;
}
int base = 1;
int temp_res = 2;
for(int i=2; i <= number; ++i){
temp_res = temp_res + base;
base = temp_res - base;
}
return base;
}
};
Python Version:
# -*- coding:utf-8 -*-
class Solution:
def rectCover(self, number):
# write code here
if number == 0:
return 0
base = 1
temp_res = 2
for _ in range(2, number+1):
temp_res += base
base = temp_res - base
return base
Note:
- 本题中最优版本中直接一个判定条件,两个变量解决问题可以说是很巧妙了,利用
temp_res
提前计算下一轮值,利用base
存储本轮结果;