用一个大小为 m x n
的二维网格 grid
表示一个箱子。你有 n
颗球。箱子的顶部和底部都是开着的。
箱子中的每个单元格都有一个对角线挡板,跨过单元格的两个角,可以将球导向左侧或者右侧。
- 将球导向右侧的挡板跨过左上角和右下角,在网格中用
1
表示。 - 将球导向左侧的挡板跨过右上角和左下角,在网格中用
-1
表示。
在箱子每一列的顶端各放一颗球。每颗球都可能卡在箱子里或从底部掉出来。如果球恰好卡在两块挡板之间的 "V" 形图案,或者被一块挡导向到箱子的任意一侧边上,就会卡住。
返回一个大小为 n
的数组 answer
,其中 answer[i]
是球放在顶部的第 i
列后从底部掉出来的那一列对应的下标,如果球卡在盒子里,则返回 -1
。
示例 1:
输入:grid = [[1,1,1,-1,-1],[1,1,1,-1,-1],[-1,-1,-1,1,1],[1,1,1,1,-1],[-1,-1,-1,-1,-1]] 输出:[1,-1,-1,-1,-1] 解释:示例如图: b0 球开始放在第 0 列上,最终从箱子底部第 1 列掉出。 b1 球开始放在第 1 列上,会卡在第 2、3 列和第 1 行之间的 "V" 形里。 b2 球开始放在第 2 列上,会卡在第 2、3 列和第 0 行之间的 "V" 形里。 b3 球开始放在第 3 列上,会卡在第 2、3 列和第 0 行之间的 "V" 形里。 b4 球开始放在第 4 列上,会卡在第 2、3 列和第 1 行之间的 "V" 形里。
示例 2:
输入:grid = [[-1]] 输出:[-1] 解释:球被卡在箱子左侧边上。
示例 3:
输入:grid = [[1,1,1,1,1,1],[-1,-1,-1,-1,-1,-1],[1,1,1,1,1,1],[-1,-1,-1,-1,-1,-1]] 输出:[0,1,2,3,4,-1]
这题是一个模拟题,按照题目要求一步一步来即可。
这题的输入是一个二维数组,表示方格中斜线的方向,如果是1就是从左上到右下,如果是-1就是从右上到左下,这个球能从上一层落到下一层就意味着该球所在方格的左右两个斜线同方向,不然就是V字形,落不下去了。
那么这题唯一的难点就是用代码表示“左右两个斜线同方向了”,同方向其实就是都是1或者都是-1,那么不妨设一个初始变量col表示球的起始列,然后用一个变量dir表示球在列上前进或者后退的距离(其实就是1和-1),每次更新col表示球现在所处的列(col+=dir),这时候要证明斜线同方向,只需要让新的列的1或-1的值等于原本的dir即可。
可能这么说有点难理解,直接看代码再回来看会好一些。
/**
* Note: The returned array must be malloced, assume caller calls free().
*/
int* findBall(int** grid, int gridSize, int* gridColSize, int* returnSize){
int n=gridColSize[0];//列数
int *ans=(int*)malloc(n*sizeof(int));//C要提前分配内存
memset(ans,-1,n*sizeof(int));//初始化为-1,不要初始化为0,因为0表示球会落到第0列
for(int j=0;j<n;j++){
int col=j;//球一开始在的位置
for(int i=0;i<gridSize;i++){
int dir=grid[i][col];//当前方块的斜线方向
col+=grid[i][col];//新的方块
if(col<0||col>=n||grid[i][col]!=dir){//斜线不同方向或者卡到边界
col=-1;//落不下去
break;
}
}
if(col>=0){//成功落下
ans[j]=col;//一开始在第j列的小球会落到第col列
}
}
*returnSize=n;//不要忘了returnSize
return ans;
}
最后记得设置一下returnSize就ac了。