跟learnjiawa一起每天一道算法编程题,既可以增强对常用API的熟悉能力,也能增强自己的编程能力和解决问题的能力。算法和数据结构,是基础中的基础,更是笔试的重中之重。
- 不积硅步,无以至千里;
- 不积小流,无以成江海。
题目描述
Java版剑指offer编程题第10题–矩形覆盖,我们可以用21的小矩形横着或者竖着去覆盖更大的矩形。请问用n个21的小矩形无重叠地覆盖一个2*n的大矩形,总共有多少种方法?
我的想法
- 题目可以转换为:用一个长为1或者长为2的长方形(小长方形是竖着还是横着),去填充一个长为n的等宽的长方形。
- 那么问题不就转换为了前面的跳台阶问题吗?进一步就是第7题中的斐波拉契数列问题。
- 这里就不考虑会重复计算的递归了,直接采用用空间换时间的第二种解法。
解题方法1
/**
* 不知道前几天的解法也没关系,实际上很简单
* 将总的填充方法记为R(n),有下列两种情况
* 如果第一次填充选择竖着去填充,宽为1,那么剩下部分的填充方法记为R(n-1)。
* 如果第一次填充选择横着去填充,宽为2,那么剩下部分的填充方法记为R(n-2)。
* 那么有下列关系:R(n)=R(n-1)+R(n-2).
* */
public int RectCover(int n) {
//考虑n是否等于零的特殊情况
if(n==0){
return 0;
}
//建立一个集合存储n为不同值时的填充方法
ArrayList<Integer> list = new ArrayList<>();
//初始条件,n=1时,有一种填充方法
//n=2时,有两种填充方法
list.add(1);
list.add(2);
if(n <= 1){
return list.get(n-1);
}else{
//R(n)=R(n-1)+R(n-2)
for(int i = 2; i <= n; i++){
list.add(list.get(i-1)+list.get(i-2));
}
return list.get(n-1);
}
}
代码测试
package com.learnjiawa.jzoffer;
import java.util.ArrayList;
/**
* @author learnjiawa
* 2019-12-09-10:12
*/
public class Solution10 {
public static void main(String[] args) {
int n = 5;
System.out.println("长为"+n+"的长方形"+RectCover(n)+"种填充方法");
}
/**
* 不知道前几天的解法也没关系,实际上很简单
* 将总的填充方法记为R(n),有下列两种情况
* 如果第一次填充选择竖着去填充,宽为1,那么剩下部分的填充方法记为R(n-1)。
* 如果第一次填充选择横着去填充,宽为2,那么剩下部分的填充方法记为R(n-2)。
* 那么有下列关系:R(n)=R(n-1)+R(n-2).
* */
public static int RectCover(int n) {
//考虑n是否等于零的特殊情况
if(n==0){
return 0;
}
//建立一个集合存储n为不同值时的填充方法
ArrayList<Integer> list = new ArrayList<>();
//初始条件,n=1时,有一种填充方法
//n=2时,有两种填充方法
list.add(1);
list.add(2);
if(n <= 1){
return list.get(n-1);
}else{
//R(n)=R(n-1)+R(n-2)
for(int i = 2; i <= n; i++){
list.add(list.get(i-1)+list.get(i-2));
}
return list.get(n-1);
}
}
}
测试代码控制台输出:
总结
题目主要考察递归和循环的相关知识点,找到规律迅速解题。
参考文献
[1]程杰. 大话数据结构. 北京:清华大学出版社, 2011.
更多
对我的文章感兴趣,点个关注是对我最大的支持,持续更新中…
关注微信公众号LearnJava: