我们可以用 2*1 的小矩形横着或者竖着去覆盖更大的矩形。请问用 n 个 2*1 的小矩形无重叠地覆盖一个 2*n 的大矩形,从同一个方向看总共有多少种不同的方法?
数据范围:
进阶:空间复杂度 ,时间复杂度
进阶:空间复杂度 ,时间复杂度
注意:约定 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)
代码: