|
| 1 | +### 题目描述 |
| 2 | + |
| 3 | +这是 LeetCode 上的 **[1706. 球会落何处](https://leetcode-cn.com/problems/where-will-the-ball-fall/solution/gong-shui-san-xie-jian-dan-mo-ni-ti-by-a-jz6f/)** ,难度为 **中等**。 |
| 4 | + |
| 5 | +Tag : 「模拟」 |
| 6 | + |
| 7 | + |
| 8 | + |
| 9 | +用一个大小为 `m x n` 的二维网格 $grid$ 表示一个箱子。你有 $n$ 颗球。箱子的顶部和底部都是开着的。 |
| 10 | + |
| 11 | +箱子中的每个单元格都有一个对角线挡板,跨过单元格的两个角,可以将球导向左侧或者右侧。 |
| 12 | + |
| 13 | +* 将球导向右侧的挡板跨过左上角和右下角,在网格中用 $1$ 表示。 |
| 14 | +* 将球导向左侧的挡板跨过右上角和左下角,在网格中用 $-1$ 表示。 |
| 15 | + |
| 16 | +在箱子每一列的顶端各放一颗球。每颗球都可能卡在箱子里或从底部掉出来。如果球恰好卡在两块挡板之间的 `"V"` 形图案,或者被一块挡导向到箱子的任意一侧边上,就会卡住。 |
| 17 | + |
| 18 | +返回一个大小为 $n$ 的数组 $answer$ ,其中 $answer[i]$ 是球放在顶部的第 $i$ 列后从底部掉出来的那一列对应的下标,如果球卡在盒子里,则返回 $-1$ 。 |
| 19 | + |
| 20 | +示例 1: |
| 21 | + |
| 22 | +``` |
| 23 | +输入: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]] |
| 24 | +
|
| 25 | +输出:[1,-1,-1,-1,-1] |
| 26 | +
|
| 27 | +解释:示例如图: |
| 28 | +b0 球开始放在第 0 列上,最终从箱子底部第 1 列掉出。 |
| 29 | +b1 球开始放在第 1 列上,会卡在第 2、3 列和第 1 行之间的 "V" 形里。 |
| 30 | +b2 球开始放在第 2 列上,会卡在第 2、3 列和第 0 行之间的 "V" 形里。 |
| 31 | +b3 球开始放在第 3 列上,会卡在第 2、3 列和第 0 行之间的 "V" 形里。 |
| 32 | +b4 球开始放在第 4 列上,会卡在第 2、3 列和第 1 行之间的 "V" 形里。 |
| 33 | +``` |
| 34 | +示例 2: |
| 35 | +``` |
| 36 | +输入:grid = [[-1]] |
| 37 | +
|
| 38 | +输出:[-1] |
| 39 | +
|
| 40 | +解释:球被卡在箱子左侧边上。 |
| 41 | +``` |
| 42 | +示例 3: |
| 43 | +``` |
| 44 | +输入: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]] |
| 45 | +
|
| 46 | +输出:[0,1,2,3,4,-1] |
| 47 | +``` |
| 48 | + |
| 49 | +提示: |
| 50 | +* $m == grid.length$ |
| 51 | +* $n == grid[i].length$ |
| 52 | +* $1 <= m, n <= 100$ |
| 53 | +* $grid[i][j]$ 为 $1$ 或 $-1$ |
| 54 | + |
| 55 | +--- |
| 56 | + |
| 57 | +### 模拟 |
| 58 | + |
| 59 | +数据范围只有 $100$,直接模拟每个球从顶部的某列出发,最终到底底部哪列即可(如果可以到达的话)。 |
| 60 | + |
| 61 | +我们使用 `r` 和 `c` 表示小球当前所处的位置,受重力影响,在不被卡住的情况下,`r` 会持续自增,直到到达底部,而 `c` 的变化,则是取决于当前挡板 `grid[r][c]` 的方向,若 `grid[r][c]` 为 $1$,则小球的下一个位置为 $(r + 1, c + 1)$;若 `grid[r][c]` 为 $-1$,则下一位置为 $(r + 1, c - 1)$,即可以统一表示为 $(r + 1, c + grid[r][c])$。当且仅当小球在本次移动过程中没被卡住,才能继续移动。即只有 $c + grid[r][c]$ 没有超过矩阵的左右边界(被边界卡住),或者 $grid[r][c]$ 和 $grid[r][c + grid[r][c]]$ 同向(不形成夹角),小球方能继续移动。 |
| 62 | + |
| 63 | +代码: |
| 64 | +```Java |
| 65 | +class Solution { |
| 66 | + int m, n; |
| 67 | + int[][] g; |
| 68 | + public int[] findBall(int[][] grid) { |
| 69 | + g = grid; |
| 70 | + m = g.length; n = g[0].length; |
| 71 | + int[] ans = new int[n]; |
| 72 | + for (int i = 0; i < n; i++) ans[i] = getVal(i); |
| 73 | + return ans; |
| 74 | + } |
| 75 | + int getVal(int x) { |
| 76 | + int r = 0, c = x; |
| 77 | + while (r < m) { |
| 78 | + int ne = c + g[r][c]; |
| 79 | + if (ne < 0 || ne >= n) return -1; |
| 80 | + if (g[r][c] != g[r][ne]) return -1; |
| 81 | + r++; c = ne; |
| 82 | + } |
| 83 | + return c; |
| 84 | + } |
| 85 | +} |
| 86 | +``` |
| 87 | +* 时间复杂度:$O(m * n)$ |
| 88 | +* 空间复杂度:$O(n)$ |
| 89 | + |
| 90 | +--- |
| 91 | + |
| 92 | +### 最后 |
| 93 | + |
| 94 | +这是我们「刷穿 LeetCode」系列文章的第 `No.1706` 篇,系列开始于 2021/01/01,截止于起始日 LeetCode 上共有 1916 道题目,部分是有锁题,我们将先把所有不带锁的题目刷完。 |
| 95 | + |
| 96 | +在这个系列文章里面,除了讲解解题思路以外,还会尽可能给出最为简洁的代码。如果涉及通解还会相应的代码模板。 |
| 97 | + |
| 98 | +为了方便各位同学能够电脑上进行调试和提交代码,我建立了相关的仓库:https://github.com/SharingSource/LogicStack-LeetCode 。 |
| 99 | + |
| 100 | +在仓库地址里,你可以看到系列文章的题解链接、系列文章的相应代码、LeetCode 原题链接和其他优选题解。 |
| 101 | + |
0 commit comments