[LeetCode解题报告] 1706. 球会落何处

一、 题目

1. 题目描述

用一个大小为 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]

提示:

  • m == grid.length
  • n == grid[i].length
  • 1 <= m, n <= 100
  • grid[i][j]1-1
Related Topics
  • 深度优先搜索
  • 数组
  • 动态规划
  • 矩阵
  • 模拟

  • 👍 133
  • 👎 0

2. 原题链接

链接: 1706. 球会落何处

二、 解题报告

1. 思路分析

 直接DP模拟或者DFS都可以,判断条件写的细一点就行。
 DFS的话试了下记忆化还不如朴素,应该是数据弱
 DP的话可以多开一行,直接作为结果。

2. 复杂度分析

最坏时间复杂度O(nlog2n)

3. 代码实现

dp

class Solution:
    def findBall(self, grid: List[List[int]]) -> List[int]:
        m,n = len(grid),len(grid[0])
        # @cache
        # def dfs(x,y):
        #     # 第x排,第y列的小球从底部哪里掉出来
        #     # 记忆化比不记忆还慢
        #     if x == m-1:
        #         if grid[x][y] == 1:
        #             if y == n - 1 or grid[x][y+1] == -1:
        #                 return -1
        #             return y+1
        #         elif grid[x][y] == -1:
        #             if y == 0 or grid[x][y-1] == 1:
        #                 return -1
        #             return y - 1                
        #     if grid[x][y] == 1:
        #         if y == n - 1 or grid[x][y+1] == -1:
        #             return -1
        #         return dfs(x+1,y+1)      
        #     elif grid[x][y] == -1:
        #         if y == 0 or grid[x][y-1] == 1:
        #             return -1
        #         return dfs(x+1,y-1)         
        # ans = [dfs(0,i) for i in range(n)] 


        dp = [[-1]*n for _ in range(m+1)]  # 记录小球j在落到第i层的位置
        dp[0] = list(range(n))
        for i in range(1,m+1):
            for j in range(0,n):
                pos = dp[i-1][j]
                if pos == -1:
                    continue
                g = grid[i-1][pos]
                if g == 1:
                    if pos == n-1 or grid[i-1][pos+1] == -1:
                        continue
                    dp[i][j] = pos + 1
                elif g == -1:
                    if pos == 0 or grid[i-1][pos-1] == 1:
                        continue
                    dp[i][j] = pos -1
        # print(dp)
        ans = dp[m]                                                  
        
        return ans

"""
\ \ \ \ \ \
/ / / / / /
\ \ \ \ \ \
/ / / / / /
"""

三、 本题小结

  1. DFS简单点
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值