我们依次判断每个球的最终位置。对于每个球,从上至下判断球位置的移动方向。在对应的位置,如果挡板向右偏,则球会往右移动;如果挡板往左偏,则球会往左移动。若移动过程中碰到侧边或者 V 型,则球会停止移动,卡在箱子里。如果可以完成本层的移动,则继续判断下一层的移动方向,直到落出箱子或者卡住。
代码
[sol1-Python3]
1 2 3 4 5 6 7 8 9 10 11 12 13 14
classSolution: deffindBall(self, grid: List[List[int]]) -> List[int]: n = len(grid[0]) ans = [-1] * n for j inrange(n): col = j # 球的初始列 for row in grid: dir = row[col] col += dir# 移动球 if col < 0or col == n or row[col] != dir: # 到达侧边或 V 形 break else: # 成功到达底部 ans[j] = col return ans
classSolution { public: vector<int> findBall(vector<vector<int>> &grid){ int n = grid[0].size(); vector<int> ans(n); for (int j = 0; j < n; ++j) { int col = j; // 球的初始列 for (auto &row : grid) { int dir = row[col]; col += dir; // 移动球 if (col < 0 || col == n || row[col] != dir) { // 到达侧边或 V 形 col = -1; break; } } ans[j] = col; // col >= 0 为成功到达底部 } return ans; } };
[sol1-Java]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
classSolution { publicint[] findBall(int[][] grid) { intn= grid[0].length; int[] ans = newint[n]; for (intj=0; j < n; j++) { intcol= j; // 球的初始列 for (int[] row : grid) { intdir= row[col]; col += dir; // 移动球 if (col < 0 || col == n || row[col] != dir) { // 到达侧边或 V 形 col = -1; break; } } ans[j] = col; // col >= 0 为成功到达底部 } return ans; } }
[sol1-C#]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
publicclassSolution { publicint[] FindBall(int[][] grid) { int n = grid[0].Length; int[] ans = newint[n]; for (int j = 0; j < n; j++) { int col = j; // 球的初始列 foreach (int[] row in grid) { int dir = row[col]; col += dir; // 移动球 if (col < 0 || col == n || row[col] != dir) { // 到达侧边或 V 形 col = -1; break; } } ans[j] = col; // col >= 0 为成功到达底部 } return ans; } }
[sol1-Golang]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
funcfindBall(grid [][]int) []int { n := len(grid[0]) ans := make([]int, n) for j := range ans { col := j // 球的初始列 for _, row := range grid { dir := row[col] col += dir // 移动球 if col < 0 || col == n || row[col] != dir { // 到达侧边或 V 形 col = -1 break } } ans[j] = col // col >= 0 为成功到达底部 } return ans }
[sol1-C]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
int* findBall(int** grid, int gridSize, int* gridColSize, int* returnSize) { int n = gridColSize[0]; int * ans = (int *)malloc(sizeof(int) * n); for (int j = 0; j < n; ++j) { int col = j; // 球的初始列 for (int i = 0; i < gridSize; i++) { int dir = grid[i][col]; col += dir; // 移动球 if (col < 0 || col == n || grid[i][col] != dir) { // 到达侧边或 V 形 col = -1; break; } } ans[j] = col; // col >= 0 为成功到达底部 } *returnSize = n; return ans; }
[sol1-JavaScript]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
var findBall = function(grid) { const n = grid[0].length; const ans = newArray(n); for (let j = 0; j < n; j++) { let col = j; // 球的初始列 for (const row of grid) { const dir = row[col]; col += dir; // 移动球 if (col < 0 || col === n || row[col] !== dir) { // 到达侧边或 V 形 col = -1; break; } } ans[j] = col; // col >= 0 为成功到达底部 } return ans; };
复杂度分析
时间复杂度:O(m \times n),其中 m 和 n 是网格的行数和列数。外循环消耗 O(n),内循环消耗 O(m)。