没有输出的输入是不完整的

0%

剑指offer-矩形覆盖

本文为剑指 offer 系列第十二篇。
主要知识点为斐波那契数列,只是需要先对问题进行分析,同样还是用三种方式来解决这个问题。

题目描述

我们可以用 2*1 的小矩形横着或者竖着去覆盖更大的矩形。请问用n个21的小矩形无重叠地覆盖一个2n的大矩形,总共有多少种方法?

解题思路

方便解释起见,我们假设整个横着的就是一个宽为2,长为n的大矩形,下面分情况讨论。

  1. n = 0 : 结果为0
  2. n = 1 : 结果为1,竖着一个。
  3. n = 2 : 结果为2 竖着两个或者横着两个。
  4. n = 3 : 结果为3,在n=1的基础上横排两个,或者在n=2的基础上竖着加一个。
  5. ……
    综上,我们就得到结论:f(n) = f(n-1)+f(n-2) 初始项为{0,1,2}

思路1

直接用递归。

思路2

用数组保存

思路3

保存两个关键数字。

解题代码

思路1代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class Solution {
public:
int rectCover(int n) {
// 方法1 直接用递归。
if(n == 0){
return 0;
}else if(n == 1){
return 1;
}else if(n == 2){
return 2;
}else{
return rectCover(n-1)+rectCover(n-2);
}
}
};

时间复杂度为O(n^2),空间复杂度为O(n)

思路2代码

1
2
3
4
5
6
7
8
9
10
11
class Solution {
public:
int rectCover(int n) {
//方法2: 数组保存
vector<int> res = {0,1,2};
for(int i = 2;i < n; i++){
res.push_back(res[i]+res[i-1]);
}
return res[n];
}
};

时间复杂度为O(n),空间复杂度为O(n)

思路3代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class Solution {
public:
int rectCover(int n) {
// 方法3. 用两个关键变量进行保存。
if(n==0) return 0;
if(n == 1) return 1;
if(n == 2) return 2;
int first = 1,second = 2;
for(int i = 2; i < n; i++){
int temp = first+second;
first = second;
second = temp;
}
return second;
}
};

时间复杂度为O(n),空间复杂度为O(1)

以上,本题结束!