我们可以用 2*1 的小矩形横着或者竖着去覆盖更大的矩形。请问用 n 个 2*1 的小矩形无重叠地覆盖一个 2*n 的大矩形,从同一个方向看总共有多少种不同的方法?
数据范围:
进阶:空间复杂度 ,时间复杂度
进阶:空间复杂度 ,时间复杂度
注意:约定 n == 0 时,输出 0
比如n=3时,2*3的矩形块有3种不同的覆盖方法(从同一个方向看):
2*1的小矩形的总个数n
覆盖一个2*n的大矩形总共有多少种不同的方法(从同一个方向看)
0
0
1
1
4
5
# -*- coding:utf-8 -*- class Solution: def rectCover(self, number): # write code here res=[0,1,2,3] if number<=3: return res[number] else: for i in range(4,number+1): res.append(res[i-1]+res[i-2]) return res[number]
# -*- coding:utf-8 -*- class Solution: def rectCover(self, number): # write code here array = [0,1,2] if number < 3: print array[number] for i in range(3,number+1): array.append(array[i-2]+array[i-1]) return array[number]
我们可以用21的小矩形横着或者竖着去覆盖更大的矩形。请问用n个21的小矩形无重叠地覆盖一个2*n的大矩形,总共有多少种方法?
比如n=3时,2*3的矩形块有3种覆盖方法:
思路分析
对于这种类型的题目,进行规律分析得出其通项公式是比较高效的方式。
规律分析 f(1)=1 f(2)=2 f(3)=3, f(3)=f(2)+f(1) f(4)=5, f(4)=f(3)+f(2)
通过规律分析,这道看似复杂的题目,其实就是斐波那契数列的应用,也是一个递归性问题,本编程题的通项公式如下:
))
问题的复杂是相对的,如果你通过思考分析出问题的根源或规律,那么问题就可以简单化。反之,没有进行思考和分析,任何问题都会被复杂化,因此进行思考和分析是直观重要的。
# -*- coding:utf-8 -*- class Solution: def rectCover(self, number): # write code here # ----------------------------------- # 增强代码鲁棒性 if number == 0: return 0 if number==1: return 1 if number==2: return 2 # ------------------------------- # 实际应用 fone,ftwo,total=1,2,0 for i in range(3,number+1): # 规律 #f(1)=1 #f(2)=2 #f(3)=3, f(3)=f(2)+f(1) #f(4)=5, f(4)=f(3)+f(2) total=fone+ftwo fone,ftwo=ftwo,total return total
class Solution: def rectCover(self, number): # write code here if number == 0: return 0 elif number == 1: return 1 elif number == 2: return 2 else: a = 1 b = 2 for i in range(3,number+1): a,b = b,a + b return b
# -*- coding:utf-8 -*- class Solution: def rectCover(self, number): # write code here if number <= 0: return 0 if number == 1: return 1 if number == 2: return 2 a = 2 b = 1 while number > 2: a = a + b b = a - b number = number - 1 return a
# -*- coding:utf-8 -*- class Solution: def rectCover(self, number): # write code here if number==0: return 0 if number==1: return 1 if number==2: return 2 dp=[0 for i in range(number+1)] dp[1]=1 dp[2]=2 for i in range(3,number+1): dp[i]=dp[i-2]+dp[i-1] return dp[-1]
和上n级楼梯一样,可以一次盖1格(长的方向) ------------ |O| | | |…… |O| | | |…… ------------ 也可以一次盖两格 ------------ |O|O| | |…… | | | | |…… ------------ 盖两格的情况,因为要全覆盖,所以下面的2*1必须和它对齐。 ------------ |O|O| | |…… |O|O| | |…… ------------
代码如下:
# -*- coding:utf-8 -*- class Solution: def rectCover(self, number): # write code here l = [0, 1, 2] for i in xrange(3, number+1): l.append(l[-1]+l[-2]) return l[number]
# -*- coding:utf-8 -*- class Solution: def rectCover(self, number): # write code here if number == 0: return 0 f = [1,1] while number - 1 > 0 : f.append(f[-1]+f[-2]) number =number -1 return f[-1]
# -*- coding:utf-8 -*- class Solution: def rectCover(self, number): # write code here if number==0: return 0 elif number==1: return 1 elif number==2: return 2 else: fib0=1 fib1=2 for i in range(number-2): fib2=fib0+fib1 fib0=fib1 fib1=fib2 return fib2 #return (self.rectCover(number-1)+self.rectCover(number-2))
(self.rectCover(number-1)+self.rectCover(number-2))所以正向计算,比较迅速
第一次摆放一块1*2的小矩阵,则摆放方法总共为f(target-2)
代码: