列表

详情


1706. 球会落何处

用一个大小为 m x n 的二维网格 grid 表示一个箱子。你有 n 颗球。箱子的顶部和底部都是开着的。

箱子中的每个单元格都有一个对角线挡板,跨过单元格的两个角,可以将球导向左侧或者右侧。

在箱子每一列的顶端各放一颗球。每颗球都可能卡在箱子里或从底部掉出来。如果球恰好卡在两块挡板之间的 "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]

 

提示:

原站题解

去查看

上次编辑到这里,代码来自缓存 点击恢复默认模板
class Solution { public: vector<int> findBall(vector<vector<int>>& grid) { } };

rust 解法, 执行用时: 0 ms, 内存消耗: 2.4 MB, 提交时间: 2025-02-15 09:36:36

impl Solution {
    pub fn find_ball(grid: Vec<Vec<i32>>) -> Vec<i32> {
        let n = grid[0].len();
        let mut ans = vec![0; n];
        for j in 0..n {
            // 模拟第 j 列球的移动
            let mut cur_col = j as i32; // 当前列号
            for row in &grid {
                let d = row[cur_col as usize]; // -1 或 1,表示左/右
                cur_col += d; // 左/右走一步
                // 如果球出界或者卡在 V 形,退出循环,否则继续循环(垂直落入下一排)
                // V 形就是 -1 的左边是 1,1 的右边是 -1,即 row[cur_col] != d
                if cur_col < 0 || cur_col as usize == n || row[cur_col as usize] != d {
                    cur_col = -1;
                    break;
                }
            }
            ans[j] = cur_col;
        }
        ans
    }
}

cpp 解法, 执行用时: 3 ms, 内存消耗: 16.8 MB, 提交时间: 2025-02-15 09:36:22

class Solution {
public:
    vector<int> findBall(vector<vector<int>>& grid) {
        int n = grid[0].size();
        vector<int> ans(n);
        for (int j = 0; j < n; j++) {
            // 模拟第 j 列球的移动
            int cur_col = j; // 当前列号
            for (auto& row : grid) {
                int d = row[cur_col]; // -1 或 1,表示左/右
                cur_col += d; // 左/右走一步
                // 如果球出界或者卡在 V 形,退出循环,否则继续循环(垂直落入下一排)
                // V 形就是 -1 的左边是 1,1 的右边是 -1,即 row[cur_col] != d
                if (cur_col < 0 || cur_col == n || row[cur_col] != d) {
                    cur_col = -1;
                    break;
                }
            }
            ans[j] = cur_col;
        }
        return ans;
    }
};

java 解法, 执行用时: 2 ms, 内存消耗: 44.4 MB, 提交时间: 2025-02-15 09:36:09

class Solution {
    public int[] findBall(int[][] grid) {
        int n = grid[0].length;
        int[] ans = new int[n];
        for (int j = 0; j < n; j++) {
            // 模拟第 j 列球的移动
            int curCol = j; // 当前列号
            for (int[] row : grid) {
                int d = row[curCol]; // -1 或 1,表示左/右
                curCol += d; // 左/右走一步
                // 如果球出界或者卡在 V 形,退出循环,否则继续循环(垂直落入下一排)
                // V 形就是 -1 的左边是 1,1 的右边是 -1,即 row[curCol] != d
                if (curCol < 0 || curCol == n || row[curCol] != d) {
                    curCol = -1;
                    break;
                }
            }
            ans[j] = curCol;
        }
        return ans;
    }
}

javascript 解法, 执行用时: 68 ms, 内存消耗: 42.8 MB, 提交时间: 2022-11-26 17:18:42

/**
 * @param {number[][]} grid
 * @return {number[]}
 */
var findBall = function(grid) {
    const n = grid[0].length;
    const ans = new Array(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;
};

golang 解法, 执行用时: 16 ms, 内存消耗: 6.5 MB, 提交时间: 2022-11-26 17:18:19

func findBall(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
}

python3 解法, 执行用时: 40 ms, 内存消耗: 15.2 MB, 提交时间: 2022-11-26 17:18:06

'''
我们依次判断每个球的最终位置。对于每个球,从上至下判断球位置的移动方向。
在对应的位置,如果挡板向右偏,则球会往右移动;如果挡板往左偏,则球会往左移动。
若移动过程中碰到侧边或者 V 型,则球会停止移动,卡在箱子里。
如果可以完成本层的移动,则继续判断下一层的移动方向,直到落出箱子或者卡住。
'''
class Solution:
    def findBall(self, grid: List[List[int]]) -> List[int]:
        n = len(grid[0])
        ans = [-1] * n
        for j in range(n):
            col = j  # 球的初始列
            for row in grid:
                dir = row[col]
                col += dir  # 移动球
                if col < 0 or col == n or row[col] != dir:  # 到达侧边或 V 形
                    break
            else:  # 成功到达底部
                ans[j] = col
        return ans

上一题