在线题目链接:矩形覆盖

文章目录

  • 1 题目描述
  • 2 题目分析
  • 3 代码
    • 3.1 递归方法
      • 3.11 Java代码
      • 3.12 C++代码
    • 3.2 动态规划算法
    • 3.2 动态规划
      • 3.21 Java代码
      • 3.22 C++代码
    • 3.3 循环方法
      • 3.31 Java代码
      • 3.32 C++代码
  • 4、总结

1 题目描述

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

2 题目分析

乍一看感觉无从下手!!!其实如果我们使用归纳方法的话,总能够总结出规律来。

假设下面是一个2*n的大矩形:

我们要使用下面这样的2*1的小矩形来填满上述的大矩形:

我们假设将2*n的矩形填满需要f(n)种方法

那么填充的方法可以有下面的两种方法:

  1. 如下图:2*1的矩形竖着放,那么还剩下2*(n-1)大小的矩形需要填,也就是剩下的矩形还有f(n-1)的方法填满

  1. 如下图:2*1的矩形横着放,那么由于它下面的也只能横这放,所以还剩下2*(n-2)个矩形,也就是剩下的矩形需要有f(n-2)种方法填满。

很明显,到这里我们就可以列出一个公式:

  • f(n)=f(n-1)+f(n-2)

这个公式我们太熟悉了,这就是斐波那契数列,我们看下面三篇文章的算法题都是这个公式的应用:

  • 斐波那契数列
  • 跳台阶
  • 变态跳台阶

综上以及题目要求,我们得出综合公式(n=0时f(n)=0):

由此可以写出三种不同的代码:递归,动态规划,循环

3 代码

3.1 递归方法

递归方法很简单,直接利用公式即可。

3.11 Java代码

public class Solution {public int RectCover(int target) {//递归if(target<3)return target;return RectCover(target-1)+RectCover(target-2);}
}

3.12 C++代码

class Solution {public:int rectCover(int number) {//递归if(number<3)return number;return rectCover(number-1)+rectCover(number-2);}
};

我们都知道这种递归解法会有很多重复的计算,就像下面的,假设我们要计算f(10):

计算f(10),要重复计算两次f(8),三次f(7),三次f(6),这种重复计算,对于数据比价大的时候,开销是非常大的。所以我们经常说,递归虽然好写,但是不建议在实现算法的时候使用递归算法。

3.2 动态规划算法

3.2 动态规划

凡是能用递归写出的代码,一定能够用动态规划写出来。

我们知道递归是为了求某一个值,而必须先知道另外的几个值后才能求出来。而想要求那另外的几个值,还需要再求另外的另外的值,就像上面的递归二叉树,想要先求f(10),必须知道f(9)和发(8)。想要知道f(9)又得知道f(8)和f(7)…

上面递归是想要计算总体值,需要求局部的值,想要求局部的值,又要求局部的局部的值。

动态规划不是这样,动态规划是先从递归的终止条件开始计算,也就是说,动态规划先计算局部的值,然后根据局部的值的累积,最终得到整体要求的值。也就是与递归反过来了。

比如针对上面的求f(10),我们先求f(1),f(2),f(3)…最终肯定会求得f(10)。这样我们就没有进行重复的计算。每一项都是只计算一次。

看代码就能明白上面说的是什么意思了。下面的ret数组,ret[i]代表斐波那契数组的第i项。我们要求得第n项,最后求到ret[n]直接返回即可。

3.21 Java代码

public class Solution {public int RectCover(int target) {//这同样是斐波那契数列 f(n)=f(n-1)+f(n-2)//动态规划if(target<=2)return target;int[] ret=new int[target+1];ret[1]=1;ret[2]=2;int i;for(i=3;i<=target;i++){ret[i]=ret[i-1]+ret[i-2];}return ret[target];}
}

3.22 C++代码

class Solution {public:int rectCover(int number) {//这同样是斐波那契数列 f(n)=f(n-1)+f(n-2)//动态规划//if(number<=2)return number;int ret[number+1];ret[0]=0;ret[1]=1;ret[2]=2;int i;for(i=3;i<=number;i++){ret[i]=ret[i-1]+ret[i-2];}return ret[number];}
};

3.3 循环方法

所有的递归都可以写成动态规划,同理所有的动态规划,也一定能写成循环。只不过有的动态规划不好写成循环而已。本题是非常好写成循环的。

循环比动态规划好的原因在于,循环只用几个变量,循环使用它们得到最终结果,不保存之前的计算结果,动态规划却需要开辟一个数组,将所有计算过的结果保存,这很浪费空间。

3.31 Java代码

public class Solution {public int RectCover(int target) {//循环if(target<3)return target;int r1=1,r2=2,ret=0;int i;for(i=3;i<=target;i++){ret=r1+r2;r1=r2;r2=ret;}return ret;}
}

当然,上面使用三个变量,我们还可以再减少一个变量,使用两个变量:

public class Solution {public int RectCover(int target) {//循环,更加单的写法if(target<3)return target;int r1=1,r2=2;int i;for(i=3;i<=target;i++){r2+=r1;r1=r2-r1;}return r2;}
}

3.32 C++代码

三个变量

class Solution {public:int rectCover(int number) {//循环if(number<3)return number;int r1=1,r2=2,ret=0;int i;for(i=3;i<=number;i++){ret=r1+r2;r1=r2;r2=ret;}return ret;}
};

两个变量

class Solution {public:int rectCover(int number) {//循环,更加单的写法if(number<3)return number;int r1=1,r2=2;int i;for(i=3;i<=number;i++){r2+=r1;r1=r2-r1;}return r2;}
};

4、总结

注意学会递归,动态规划,循环三者时间的关系

探讨学习加:
个人qq:1126137994
个人微信:liu1126137994

【剑指offer - C++/Java】10、矩形覆盖相关推荐

  1. 剑指offer面试题[9-3]-矩形覆盖

    题目描述 我们可以用2*1的小矩形横着或者竖着去覆盖更大的矩形.请问用n个2*1的小矩形无重叠地覆盖一个2*n的大矩形,总共有多少种方法? 分析: (1) n等于1时,总共有1种方法.     (2) ...

  2. 剑指Offer(java答案)

    剑指Offer(java答案) 剑指Offerjava答案 3二维数组中的查找 4替换空格 5从尾到头打印链表 6重建二叉树 7用两个栈实现队列 8旋转数组的最小数字 9斐波那契数列 扩展1跳台阶 扩 ...

  3. 【剑指offer】Java版代码(完整版)

    参考链接 [剑指offer]Java版代码(完整版)

  4. 剑指offer——面试题10:二进制中1的个数

    剑指offer--面试题10:二进制中1的个数 关于负数的自己没想出来,这是书中的两种算法,关于位运算的知识还是得要学习一个啊... Solution1: class Solution {public ...

  5. 《剑指Offer》Java刷题 NO.36 两个链表的第一个公共结点(链表,等长拼接法,长者先行法,辅助栈)

    <剑指Offer>Java刷题 NO.36 两个链表的第一个公共结点(链表,等长拼接法,长者先行法,辅助栈) 传送门:<剑指Offer刷题总目录> 时间:2020-06-19 ...

  6. java计算整数出现的次数_[剑指offer题解][Java]1到n整数中1出现的次数

    前言 众所周知,<剑指offer>是一本"好书". 如果你是个算法菜鸡(和我一样),那么最推荐的是先把剑指offer的题目搞明白. 对于剑指offer题解这个系列,我的 ...

  7. java剑指offer_剑指offer题目java实现

    Problem2:实现Singleton模式 题目描述:设计一个类,我们只能生成该类的一个实例 1 packageProblem2;2 3 public classSingletonClass {4 ...

  8. 剑指offer:java版

    作者:CyC2018 链接:https 文章目录 一.基础 3.数组中的重复的数字 4. 二维数组中的查找 5. 替换空格 6. 从尾到头打印链表 7. 重建二叉树 8. 二叉树的下一个结点 9. 用 ...

  9. java 最大子数组_[剑指offer题解][Java]连续子数组的最大和

    前言 众所周知,<剑指offer>是一本"好书". 如果你是个算法菜鸡(和我一样),那么最推荐的是先把剑指offer的题目搞明白. 对于剑指offer题解这个系列,我的 ...

  10. 剑指offer | 面试题10:斐波那切数列

    转载本文章请标明作者和出处 本文出自<Darwin的程序空间> 本文题目和部分解题思路来源自<剑指offer>第二版 开始行动,你已经成功一半了,献给正在奋斗的我们 题目 求斐 ...

最新文章

  1. python3.6安装pyqt5-Python3.6安装PyQt5的方法
  2. create maven android project
  3. IDEA出现Error during artifact deployment. See server log for details.
  4. C++实现折半插入排序
  5. 一次搞定各种数据库SQL执行计划
  6. 让你惊叹的 Markdown 写作工具推荐
  7. 用html编写你好,02 - HTML5第一个项目:HelloWorld!(收藏)
  8. 把python安装到u盘无法使用_U盘无法使用不能用怎么办解决教程
  9. 洛谷——P1307 [NOIP2011 普及组] 数字反转
  10. C/C++对文件的读写
  11. Linux安装vim命令
  12. [推荐]15款非常好用的新浪,腾讯短链接生成器,一次生成永不失效,巨好用!
  13. 一二线城市知名 IT 互联网公司名单公布!
  14. 「笔耕不辍」mysql的存储引擎详解
  15. pyqt5 设置动态背景图片
  16. token登录最详细代码实例
  17. 以华为公司为例的我国业务流程管理实践研究
  18. 想看懂资管行业?不清楚有哪些资管产品怎么行!
  19. 亿图图示----科学与软件展示
  20. 在线制作banner的网站

热门文章

  1. Linux 进程通信 -- 信号
  2. 南邮 计算机网络,南邮计算机网络_期末复习纲要-精简版教材.pdf
  3. vue computed使用_vue computed正确使用方式
  4. 《JAVA核心技术》
  5. Jmeter之逻辑控制器(Logic Controller)
  6. hdu 4738 Caocao's Bridges 求无向图的桥【Tarjan】
  7. 刚学unity3d,跟着仿作了flappy bird,记下一些琐碎的心得!
  8. jacob 实现Office Word文件格式转换
  9. 基于visual Studio2013解决C语言竞赛题之0304整除数
  10. 使用 Jackson 树连接线形状