时间:2025-07-09 09:00
人气:
作者:admin
我们可以用 2 * 1 的小矩形横着或者竖着去覆盖更大的矩形。请问用n个 2 * 1 的小矩形无重叠地覆盖一个2 * n的大矩形,总共有多少种方法?
比如n=3时,2 * 3 的矩形块有3种覆盖方法:

我们需要用若干个2×1的小矩形(可以横放或竖放)无重叠地覆盖一个2×n的大矩形,求总共有多少种不同的覆盖方法。例如当n=3时,共有3种覆盖方法。
通过观察小规模案例,我们可以发现:
显然,这形成了一个类似斐波那契数列的规律:f(n) = f(n-1) + f(n-2)。这一题其实和上面青蛙跳台阶和斐波那契数列是一样的,变的只是场景。
递归是解决这类问题最直观的方法。对于2×n的矩形,我们考虑第一块小矩形的放置方式:
因此,总方法数为这两种情况之和:f(n) = f(n-1) + f(n-2),这正是斐波那契数列的递推关系
public class Solution {
public int rectCover(int n) {
if (n <= 0) return 0;
if (n == 1) return 1;
if (n == 2) return 2;
return rectCover(n - 1) + rectCover(n - 2);
}
}
在递归解法基础上,我们可以加入记忆化存储,避免重复计算。使用一个数组存储已经计算过的结果,每次计算前先检查是否已存储
public class Solution {
public int rectCover(int n) {
if (n <= 0) return 0;
if (n == 1) return 1;
if (n == 2) return 2;
int[] dp = new int[n + 1];
for (int i = 2; i <= n; i++) {
dp[i] = dp[i - 1] + dp[i - 2];
}
return dp[n];
}
}
观察发现,计算f(n)只需要前两个状态f(n-1)和f(n-2),因此可以用两个变量代替整个数组,将空间复杂度优化到O(1)。
public class Solution {
public int rectCover(int n) {
if (n <= 0) return 0;
if (n == 1) return 1;
if (n == 2) return 2;
int prev1 = 1, prev2 = 2;
int result = 0;
for (int i = 3; i <= n; i++) {
result = prev2 + prev1;
prev1 = prev2;
prev2 = result;
}
return result;
}
}
本文来自在线网站:seven的菜鸟成长之路,作者:seven,转载请注明原文链接:www.seven97.top
Hutool 的 `TimedCache` 到期会自动清理吗?