题目
小扣注意到秋日市集上有一个创作黑白方格画的摊位。摊主给每个顾客提供一个固定在墙上的白色画板,画板不能转动。画板上有 n * n 的网格。绘画规则为,小扣可以选择任意多行以及任意多列的格子涂成黑色(选择的整行、整列均需涂成黑色),所选行数、列数均可为 0。小扣希望最终的成品上需要有 k 个黑色格子,请返回小扣共有多少种涂色方案。
注意:两个方案中任意一个相同位置的格子颜色不同,就视为不同的方案。
示例1
输入:n = 2, k = 2
输出:4
解释:一共有四种不同的方案:
第一种方案:涂第一列;
第二种方案:涂第二列;
第三种方案:涂第一行;
第四种方案:涂第二行。
示例2
输入:n = 2, k = 1
输出:0
解释:不可行,因为第一次涂色至少会涂两个黑格
示例3
输入:n = 2, k = 4
输出:1
解释:共有 2*2=4 个格子,仅有一种涂色方案。
限制:
1 <= n <= 6
0 <= k <= n * n
一,C语言
int C(int m,int n)
{
int p=1,q=1;
for(int i=n;i>n-m;i--)
p*=i;
for(int j=m;j>1;j--)
q*=j;
return p/q;
}
int paintingPlan(int n, int k)
{
int count=0;
if(k==0||k==n*n)
return 1;
if(k<n||k>n*n)
return 0;
for(int i=0;i<=n;i++)
{
for(int j=0;j<=n;j++)
{
if(k==i*n+j*(n-i))
count+=C(i,n)*C(j,n);
}
}
return count;
}
解题思路
用count记录方案,先解决边界问题,当k=0或者k=nn是只有一种方案,当k<n(因为选中一行或一列至少要增加n个黑格)或k>nn(不存在)方案数为零。然后通过双层循环进行遍历满足in+jn-i*j=k条件的行数和列数。
最后定义一个函数进行排列组合,即return p/q;通过返回值进而计算出方案数。
知识点
1,有参函数的定义:函数可以只有一个参数,也可以有多个,多个参数之间由,分隔。参数本质上也是变量,定义时要指明类型和名称。与无参函数的定义相比,有参函数的定义仅仅是多了一个参数列表。
数据通过参数传递到函数内部进行处理,处理完成以后再通过返回值告知函数外部。
int sum(int m, int n){
int i, sum=0;
for(i=m; i<=n; i++){
sum+=i;
}
return sum;
}
参数列表中给出的参数可以在函数体中使用,使用方式和普通变量一样。
调用 sum() 函数时,需要给它传递两份数据,一份传递给 m,一份传递给 n。
二,Java
class Solution {
public int paintingPlan(int n, int k) {
int res = 0;
if(k == 0)return 1;
if(k == n * n)return 1;
for(int i = 0;i <= n;i++){
for(int j = 0;j <= n;j++)
if((i*n) + (j*n) - (i*j) == k) {
res += C(i,n) * C(j,n);
}
}
return res;
}
public int C(int x,int y){
if(x == 0)return 1;
int n = 1;
for(int i = 0;i < x;i++){
n *= (y - i);
}
for(int i = 1;i <= x;i++){
n /= i;
}
return n;
}
}
三,Python
class Solution(object):
def paintingPlan(self, n, k):
"""
:type n: int
:type k: int
:rtype: int
"""
if k in (0,n*n):
return 1
def get(n,a):
res=1
for i in range(n,n-a,-1):
res*= i
for j in range(1,a+1):
res/=j
return res
ans=0
for i in range(n):
for j in range(n):
if n*(i+j)-(i*j) ==k:
ans+=get(n,i)*get(n,j)
return ans
知识点
1,def 函数名(参数1, 参数2, ……, 参数N): 执行语句
# 定义函数
def hello():
print 'hello python!'
# 调用函数
hello(
题目
输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数。
示例1
输入:matrix = [[1,2,3],[4,5,6],[7,8,9]]
输出:[1,2,3,6,9,8,7,4,5]
示例2
输入:matrix = [[1,2,3,4],[5,6,7,8],[9,10,11,12]]
输出:[1,2,3,4,8,12,11,10,9,5,6,7]
一,C语言
int* spiralOrder(int** matrix, int matrixSize, int* matrixColSize, int* returnSize)
{
if (matrixSize == 0 || *matrixColSize == 0) {
*returnSize = 0;
return NULL;
}
*returnSize = matrixSize * (*matrixColSize);
int* ret = (int*)malloc(sizeof(int) * (*returnSize));
int q = 1;
ret[0] = matrix[0][0];
int top = 0;
int botton = matrixSize - 1;
int left = 0;
int right = *matrixColSize - 1;
int i = 0;
int j = 0;
while (top <= botton && left <= right) {
j++;
while (j <= right) {
ret[q] = matrix[i][j];
q++;
j++;
}
j--;
top += 1;
if (top > botton) {
return ret;
}
i++;
while(i <= botton) {
ret[q] = matrix[i][j];
q++;
i++;
}
i--;
right -= 1;
if (left > right) {
return ret;
}
j--;
while (j >= left) {
ret[q] = matrix[i][j];
q++;
j--;
}
j++;
botton -= 1;
if (top > botton) {
return ret;
}
i--;
while (i >= top) {
ret[q] = matrix[i][j];
q++;
i--;
}
i++;
left += 1;
if (left > right) {
return ret;
}
}
return ret;
}
解题思路
1.维护一个上下左右的index(注意不要越界)。
2.遍历的顺序是 向右(上边界向下) 向下(右边界向左) 向左(下边界向上) 向上(左边界向右)。
3.结束循环的条件就是 左右边界 或者 上下边界出现了交叉。
二,Java
方法一
class Solution {
public int[] spiralOrder(int[][] matrix) {
if(matrix.length == 0) return new int[0];
int l = 0, r = matrix[0].length - 1, t = 0, b = matrix.length - 1, x = 0;
int[] res = new int[(r + 1) * (b + 1)];
while(true) {
for(int i = l; i <= r; i++) res[x++] = matrix[t][i]; // left to right.
if(++t > b) break;
for(int i = t; i <= b; i++) res[x++] = matrix[i][r]; // top to bottom.
if(l > --r) break;
for(int i = r; i >= l; i--) res[x++] = matrix[b][i]; // right to left.
if(t > --b) break;
for(int i = b; i >= t; i--) res[x++] = matrix[i][l]; // bottom to top.
if(++l > r) break;
}
return res;
}
}
解题思路
1,先判断矩阵的长度是否为零,创建一个一维数组。
2,开始利用循环进行遍历,从左向右依次赋给res[x++],然后进行判断矩阵的行数是否大于2(主要是判断是否有进行下一步从上到下的必要),如果大于2,从上到下依次赋值给res[x++],然后在进行判断列数是否大于1,如果大于1,进行赋值。从右到左,从下到上依次进项赋值即可。
方法二
class Solution {
public int[] spiralOrder(int[][] matrix) {
if(matrix == null || matrix.length == 0 || matrix[0].length == 0)
return new int[0];
int[] ans = new int[matrix.length * matrix[0].length];
helper(matrix, 0, 0, matrix[0].length, matrix.length, ans);
return ans;
}
public void helper(int[][] matrix,int x, int y, int width, int height,int[] ans){
int count = 0;
while(width > 0 && height > 0){
for(int i = 0; i<width; i++) //读行
ans[count++] = matrix[y][x+i];
for(int i = 1; i<height; i++) //读右边列
ans[count++] = matrix[y+i][x+width-1];
if(height > 1){ //高度大于1
for(int i = width - 2; i>=0; i--) //逆序读下面一行
ans[count++] = matrix[y+height-1][x+i];
}
if(width > 1){ //宽度大于1
for(int i = height-2; i>0; i--) //逆序读左面一列
ans[count++] = matrix[y+i][x];
}
width -= 2;
height -= 2;
x += 1;
y += 1;
}
}
}
三,Python
class Solution:
def spiralOrder(self, matrix:[[int]]) -> [int]:
if not matrix: return []
l, r, t, b, res = 0, len(matrix[0]) - 1, 0, len(matrix) - 1, []
while True:
for i in range(l, r + 1): res.append(matrix[t][i]) # left to right
t += 1
if t > b: break
for i in range(t, b + 1): res.append(matrix[i][r]) # top to bottom
r -= 1
if l > r: break
for i in range(r, l - 1, -1): res.append(matrix[b][i]) # right to left
b -= 1
if t > b: break
for i in range(b, t - 1, -1): res.append(matrix[i][l]) # bottom to top
l += 1
if l > r: break
return res
知识点
1,res.append(x)
res尾部添加一个元素x。
res.count(x)
res中x的数量