黑白方格画
难度:
标签:
题目描述
English description is not available for the problem. Please switch to Chinese.
代码结果
运行时间: 22 ms, 内存: 16.0 MB
/*
题目思路:
使用Java Stream进行解答,通过组合数学的方法计算出所有可能的涂色方案,并用Stream API来优化代码。
*/
import java.util.stream.IntStream;
public class Solution {
public int paintingPlans(int n, int k) {
if (k == 0) return 1;
if (k > n * n) return 0;
return (int) IntStream.rangeClosed(0, n)
.boxed()
.flatMap(rows -> IntStream.rangeClosed(0, n)
.filter(cols -> rows * n + cols * n - rows * cols == k)
.mapToObj(cols -> combination(n, rows) * combination(n, cols)))
.mapToInt(Integer::intValue)
.sum();
}
private int combination(int n, int k) {
if (k == 0 || k == n) return 1;
if (k > n) return 0;
return IntStream.rangeClosed(1, k)
.reduce(1, (res, i) -> res * (n - i + 1) / i);
}
public static void main(String[] args) {
Solution sol = new Solution();
System.out.println(sol.paintingPlans(2, 2)); // Output: 4
System.out.println(sol.paintingPlans(2, 1)); // Output: 0
System.out.println(sol.paintingPlans(2, 4)); // Output: 1
}
}
解释
方法:
题解的思路基于组合计算和条件筛选。首先,如果需要涂的格子数k等于n*n,即整个画板全部涂黑,那么只有一种方案。否则,通过枚举涂黑的行数x和列数y,来计算符合条件的涂色方案数。对于给定的行数x,计算需要涂黑的列数y,满足条件k = nx + (n-x)y(因为涂黑x行后,剩余需要涂黑的格子数为k-n*x,这些格子必须通过涂y列得到,但要减去已经被涂黑的x行和y列重合的部分)。如果(k-n*x)可以整除(n-x),则y是一个合法的列数,计算这种情况的方案数。方案数由组合数计算得出,即选择x行的组合数乘以选择y列的组合数。
时间复杂度:
O(n^2)
空间复杂度:
O(1)
代码细节讲解
🦆
在解题思路中,当计算列数y时,使用的公式为`(k - n * x) / (n - x)`。这个公式是如何派生出来的?具体的逻辑推理是什么?
▷🦆
题解中提到,如果`k - n * x`小于0则终止循环。这里的逻辑是基于什么考虑?为什么当这个值小于0时,就不需要继续计算了?
▷🦆
解题中使用了组合数公式`comb(n, m)`,请问这个函数在计算时有没有考虑到当`m > n`的情况,即组合数应为0的边界条件?
▷