剑指offer系列之九:矩形覆盖问题

题目描述

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

我们采用从能够简单到复杂的思路思考这个问题,当n=1的时候,只有一个2*1的矩形,所以只有一种方法,记为f(1)=1;当n=2的时候,是两个2*1的矩形,这时候具有两种方式去覆盖这个矩形了(这时候应该是一个正方形),一种是竖着放,一种是横着放,所以有两种方法,记为f(2)=2;

当n=3的时候,仍然只能采用横着放或者竖着放的方式去覆盖这个矩形,我们仍首先考虑使用竖着放的方式,当竖着放的时候,由于已经覆盖了左边(假设是从左边开始覆盖的,从右边的覆盖的效果是一样的)一个2*1的矩形,所以还有2个2*1的矩形,而这种情况我们已经在n=2的时候计算出来了,就是f(2);接下来我们考虑横着放的情况,由于是横着放,在水平方向已经覆盖了一个2*1的矩形,所以要想覆盖这由3个2*1组成的矩形,只能在水平方向的覆盖的那个矩形下面继续覆盖一个,那么只剩下一个2*1的矩形了,这也通过前面的分析计算出来了,就是f(1)。综合以上分析,当n=3的时候,覆盖的方法是f(3)=f(1)+f(2)。

其他以此类推,我们发现这仍然是一个斐波那契数列,所以我们写出如下代码(已被牛客AC):

public int RectCover(int target) {
        if(target <= 0) return 1;
        if(target == 1 || target == 2) return target;
        return RectCover(target - 1) + RectCover(target - 2);
    }
时间: 2024-09-29 20:41:03

剑指offer系列之九:矩形覆盖问题的相关文章

剑指offer系列之二十六:输出字符串的全排列

题目描述 输入一个字符串,按字典序打印出该字符串中字符的所有排列.例如输入字符串abc,则打印出由字符a,b,c所能排列出来的所有字符串abc,acb,bac,bca,cab和cba. 结果请按字母顺序输出. 输入描述: 输入一个字符串,长度不超过9(可能有字符重复),字符只包括大小写字母. 此题与剑指offer原题存在一些初入,在原题中并没有规定字符串中字符是否有重复的出现.不过思路是一致的,只不过是添加额外的判断罢了.下面说说我的思路吧:先不考虑是否出现重读字符,要对一个字符进行全排列,可以

剑指offer系列之十二:调整数组顺序使奇数位于偶数前面

题目描述 输入一个整数数组,实现一个函数来调整该数组中数字的顺序,使得所有的奇数位于数组的前半部分,所有的偶数位于位于数组的后半部分,并保证奇数和奇数,偶数和偶数之间的相对位置不变. 这道题第一思路自然是这样的:从头开始遍历这个数组,如果遇到偶数就把这个数之后的所有数往前移动一位,这样数组会留出一个空位,移动完毕之后把该偶数放到该空位即可.这样处理的话需要两次循环,一次是遍历,另一次是移位,所以时间复杂度是O(n2).下面是这种思路的实现代码(已被牛客AC): public void reOrd

剑指offer系列之三:在二维数组中查找元素

题目描述: 在一个二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序.请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数. 由于题目条件的成立,所以使得这道题可以使用对角线的方法完成,可以从右上角的元素考虑,如果目标查找元素小于右上角的元素,那么不可能在右上角元素所在的列,如果目标大于剩余列的右上角的元素,那么不可能在该右上角元素所在的行.依照这个规律,就可以完成目标元素的查找(参考剑指offer书中的思路).基于此,我写出如下的代码(已被

剑指offer系列之十九:包含min函数的栈

题目描述 定义栈的数据结构,请在该类型中实现一个能够得到栈最小元素的min函数.要求时间复杂度是O(1). 还是先说一下思路吧,因为每次方元素进栈的时候不能保证栈顶元素都是最小的,所以需要想办法使得栈顶元素始终是最小的元素,排序是一种思路,但是每次排序还设计重新出栈和入栈,想来应该不是这样的.一种思路是可以利用一个辅助栈,相当于是以空间换时间了.具体思路是:当入栈的新元素原先栈顶元素小的话就该元素放入一个辅助栈中,如果新入栈的元素比原先栈顶元素大,则在辅助栈中继续放原先最小的元素.这样一直放下去

剑指offer系列之二十九:连续子数组的最大和

题目描述 HZ偶尔会拿些专业问题来忽悠那些非计算机专业的同学.今天测试组开完会后,他又发话了:在古老的一维模式识别中,常常需要计算连续子向量的最大和,当向量全为正数的时候,问题很好解决.但是,如果向量中包含负数,是否应该包含某个负数,并期望旁边的正数会弥补它呢?例如:{6,-3,-2,7,-15,1,2,2},连续子向量的最大和为8(从第0个开始,到第3个为止).你会不会被他忽悠住? 这实际上是一个逐步比较的过程,假设累加进行到某一步,继续累加下一个数的时候发现和变小了,就应该重新计算当前累加的

剑指offer系列之四十九:数组中重复的数字

题目描述 在一个长度为n的数组里的所有数字都在0到n-1的范围内. 数组中某些数字是重复的,但不知道有几个数字是重复的.也不知道每个数字重复几次.请找出数组中任意一个重复的数字. 例如,如果输入长度为7的数组{2,3,1,0,2,5,3},那么对应的输出是重复的数字2或者3. 此题的思路还是比较简单的,与之前找出只出现一次的数字的题目有些类似,基本思路还是创建一个Map容器,key是出现的数字,value则是该数字出现的次数.在遍历数组的过程中,只要容器中已经出现了该数字,那么就直接返回给数组,

剑指offer系列之三十九:数组中只出现一次的数字

题目描述 一个整型数组里除了两个数字之外,其他的数字都出现了两次.请写程序找出这两个只出现一次的数字. 先考虑只有只有一个数字出现一次的情况,因为其他数字只出现了两次,所以对这两个数字进行异或运算的时候,其结果是0,那么那个只出现一次的数字进行异或运算的时候,其结果必然不是0,所以可以利用这点找出那个只出现一次的数字.现在考虑有两个数字出现一次的情况,仍然借鉴上面的思路,因为只出现一次的那个数字的异或结果不是0,遍历整个数组进行异或运算的结果也肯定不是0,现在可以对该数右边第一个是1的位的位置作

剑指offer系列之五十九:链表中环的入口节点

题目描述 一个链表中包含环,请找出该链表的环的入口结点. 此题的思路其实 很简单,之所以出现环,是因为在整个链表中出现了重复的节点,而遇到的第一个重复的节点就是环的入口节点.所以可以使用Set来保存遍历到的节点,因为Set集合是不允许出现重复元素的,所以当一个节点被第二次添加的时候,往Set中放元素是失败的.所以可以利用这一点找出第一个重复的元素.基于这种思路的代码比较简洁,代码如下(已被牛客AC): import java.util.HashSet; import java.util.Set;

剑指offer系列之五十一:正则表达式匹配

题目描述 请实现一个函数用来匹配包括'.'和'*'的正则表达式.模式中的字符'.'表示任意一个字符,而'*'表示它前面的字符可以出现任意次(包含0次). 在本题中,匹配是指字符串的所有字符匹配整个模式.例如,字符串"aaa"与模式"a.a"和"ab*ac*a"匹配,但是与"aa.a"和"ab*a"均不匹配 由于只涉及两种正则表达式的匹配,所以关键是需要分清除匹配的所有情况,对于模式串来讲,出现了'.'和'*