问题背景
用一个大小为 m × n m \times n m×n 的二维网格 g r i d grid grid 表示一个箱子。你有 n n n 颗球。箱子的顶部和底部都是开着的。
箱子中的每个单元格都有一个对角线挡板,跨过单元格的两个角,可以将球导向左侧或者右侧。
- 将球导向右侧的挡板跨过左上角和右下角,在网格中用 1 1 1 表示。
- 将球导向左侧的挡板跨过右上角和左下角,在网格中用 − 1 -1 −1 表示。
在箱子每一列的顶端各放一颗球。每颗球都可能卡在箱子里或从底部掉出来。如果球恰好卡在两块挡板之间的 “V” 形图案,或者被一块挡导向到箱子的任意一侧边上,就会卡住。
返回一个大小为 n n n 的数组 a n s w e r answer answer,其中 a n s w e r [ i ] answer[i] answer[i] 是球放在顶部的第 i i i 列后从底部掉出来的那一列对应的下标,如果球卡在盒子里,则返回 − 1 -1 −1。
数据约束
- m = g r i d . l e n g t h m = grid.length m=grid.length
- n = g r i d [ i ] . l e n g t h n = grid[i].length n=grid[i].length
- 1 ≤ m , n ≤ 100 1 \le m, n \le 100 1≤m,n≤100
- g r i d [ i ] [ j ] grid[i][j] grid[i][j]为 1 1 1或 − 1 -1 −1
解题过程
模拟小球移动的过程,注意先列后行,因为列的情况相对要复杂一点,卡住的情况主要概括为当前要移动的方向和当前格给定的移动方向不一致,但还要额外考虑越界的情形。
行的处理就比较简单,没卡住时向下移动一行就可以了。
具体实现
class Solution {public int[] findBall(int[][] grid) {int n = grid[0].length;int[] res = new int[n];for (int j = 0; j < n; j++) {int curCol = j;for (int[] row : grid) {// direction 表示当前格给定的横向移动方向int direction = row[curCol];// curCol 表示当前列,这里要根据所给方向进行移动curCol += direction;// 除了越界的情形,当前格所给的方向和下一格所给的方向冲突,就卡住if (curCol < 0 || curCol >= n || row[curCol] != direction) {curCol = -1;break;}}res[j] = curCol;}return res;}
}