剑指offer 11. 矩阵覆盖

原题

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

My Answer

解题思路:

依旧是典型DP,只需要找出递归规律即可。

事实上,这个规律开始并没有一眼看出,对于这种情况,可以先尝试做出几个结果之后找规律,如 n=0 时,对应 res[0] = 0res[1] = 1res[2] = 2res[3] = 3res[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 存储本轮结果;
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值