我们可以用 2*1 的小矩形横着或者竖着去覆盖更大的矩形。请问用 n 个 2*1 的小矩形无重叠地覆盖一个 2*n 的大矩形,从同一个方向看总共有多少种不同的方法?
数据范围:
进阶:空间复杂度
,时间复杂度 %5C)
进阶:空间复杂度
注意:约定 n == 0 时,输出 0
比如n=3时,2*3的矩形块有3种不同的覆盖方法(从同一个方向看):
2*1的小矩形的总个数n
覆盖一个2*n的大矩形总共有多少种不同的方法(从同一个方向看)
0
0
1
1
4
5
function rectCover(number)
{
// write code here
//
const dp = [0,1,2] // dp[i] 为要覆盖2*i范围的操作方法
// 注意初始化从 0, 1, ...n
// dp[i-1], 距离dp[i] 只有一个 | 也就只有一种方法
// dp[i-2], 距离dp[i] 有 || 或者 = 但是上一个和 dp[i-1]一样, 所以也就只有一种方法
// dp[i] = dp[i-1] + dp[i-2]
let cur = 3
while(cur<=number){ // 因为要最后取到 dp[i] 所以要相等
dp[cur] = dp[cur-1] + dp[cur-2]
cur++
}
return dp[number]
}
module.exports = {
rectCover : rectCover
};
function rectCover(number)
{
let prevOne = 2,prevTwo = 1;
if(number <= 2) prevOne = number;
for(let i = 3;i<=number;i++){
let curr = prevOne;
prevOne = prevOne + prevTwo;
prevTwo = curr
}
return prevOne
}
module.exports = {
rectCover : rectCover
}; function rectCover(number)
{
// write code here
if(number <= 0) return 0;
if(number == 1) return 1;
if(number == 2) return 2;
// return rectCover(number - 1) + rectCover(number -2);
let f = 1;
let g = 2;
while(number--) {
g += f;
f = g - f;
}
return f;
}
module.exports = {
rectCover : rectCover
}; function rectCover(number)
{
if (number == 0) return 0;
else if (number == 1) return 1;
else if (number == 2) return 2;
else return rectCover(number-1) + rectCover(number-2);
}
module.exports = {
rectCover : rectCover
}; function rectCover(number)
{
if(number === 1 || number === 2 || number === 0) {
return number
} else {
return rectCover(number - 1) + rectCover(number - 2)
}
}
//递归的写法 /**
* 我的解题思路:
* 1.枚举结果 0, 1, 2, 3, 5, 8, .... 可以知道 n > 2 时, f(n) = f(n - 1) + f(n - 2)
* 2.跟斐波那契数列一样的,递归和尾递归的方法这里就不写了,直接给动态规划的方法
*
* @param {*} number
*/
function rectCover(number)
{
// write code here
let result = number ? 1 : 0;
let temp = 1;
while (number-- > 1) {
result += temp;
temp = result - temp;
}
return result;
}
/**
* 评论区TOP的解题思路:
* 很遗憾,木得了
*
* @param {*} number
*/
function toprectCover(number)
{
// write code here
}
function rectCover(number)
{
if(number <= 0){
return 0;
}
if(number === 1){
return 1;
}
if(number === 2){
return 2;
}
let lastSolution = 1;
let solution = 2;
for(let i = 3; i <= number; i++){
let newSolution = solution + lastSolution;
lastSolution = solution;
solution = newSolution;
}
return solution;
}
function rectCover(n){if(n<=2){returnn;}let i = 2;let pre = 1;let current = 2;let result = 0;while(i++ < n){result = pre + current;pre = current;current = result;}returnresult;}
function rectCover(number)
{
var count = 1;
if(number<4){
count = number;
}else{
if(number%2==0){
count ++; //再加一种全为2的状态,当全为2时,就不进入排列组合计算
}
count += getResult(number);
}
//竖着不管,题目等价转化为至少一个2时,通过2和1排列组合占据n个位置
return count;
}
function getResult(num){
var result = 0;
var total = 0; //1和2的总数
var max2 = Math.floor(num/2); //最多有对少个2
for(var i = 1; i<=max2; i++){
var count1 = num - 2*i; //1的个数
total = i + count1;
if(count1>0){ //否则是全2的状态,已经加入了
result += methods(total,i)/methods(i,i);
}
}
return result;
}
//n表示从哪个数开始,x表示阶乘多少次
function methods(n,x){
var res =n;
if(x==1){
return n;
}else{
for(var i=1; i<x; i++){
res = res*(n-i);
}
}
return res;
}
feibonaqi数列
function rectCover(number) {
// write code here
if (number == 0) return 0;
else if (number == 1) return 1;
else if (number == 2) return 2;
var pre = 1,
next = 2;
while (--number) {
next += pre;
pre = next - pre;
}
return pre;
}
第一次摆放一块1*2的小矩阵,则摆放方法总共为f(target-2)
代码:
public class Solution { public int rectCover(int target) { if(target <= 1){ return 1; } if(target*2 == 2){ return 1; }else if(target*2 == 4){ return 2; }else{ return rectCover((target-1))+rectCover(target-2); } } }