LeetCode 1263 minimum-moves-to-move-a-box-to-their-target-location

LeetCode 1263

这个题目基本上用的就是最之间的方法。

首先考虑箱子是否能reach到终点,如果不能那么就是-1,

再次考虑在推箱子的过程中,人必须能够到达去推的位置

这两个都是可以用BFS来搜索的

    def minPushBox(self, grid: List[List[str]]) -> int:
        direct = [[0, 1, 0, -1, 0], [0, -1, 0, 1, 1], [-1, 0, 1, 0, 2], [1, 0, -1, 0, 3]]
        
        foundB = False
        foundT = False
        foundh = False
        for i in range(len(grid)):
            for j in range(len(grid[0])):
                if grid[i][j] == 'B':
                    startx = i
                    starty = j                    
                    foundB = True
                if grid[i][j] == 'T':
                    targetx = i
                    targety = j
                    foundT = True
                    grid[i][j] = '.'
                if grid[i][j] == 'S':
                    hx = i
                    hy = j
                    foundh = True
                    grid[i][j] = '.'
            if foundB and foundT and foundh:
                break

        #BFS
        visted = [[[False] * 4 for j in range(len(grid[0]))] for i in range(len(grid))]
        q = Queue()
        q.put([startx, starty, 0, hx, hy])
        visted[startx][starty] = [True, True, True, True]

        while(not q.empty()):
            current = q.get()
            if (current[0] == targetx and current[1] == targety):
                return current[2]
            grid[current[0]][current[1]] = 'B'

            for d in direct:
                newx = current[0]+d[0]
                newy = current[1]+d[1]
                pushx = current[0] + d[2]
                pushy = current[1] + d[3]
                
                if (newx >=0 and newy >=0 and newx < len(grid) and newy < len(grid[0])) and \
                   (pushx >=0 and pushy >=0 and pushx < len(grid) and pushy < len(grid[0])) and \
                   (grid[newx][newy] == '.' or grid[newx][newy] == 'S') and \
                   (grid[pushx][pushy] == '.' or grid[pushx][pushy] == 'S') and \
                   (not visted[newx][newy][d[4]]) and \
                    self.canReach(current[3], current[4], pushx, pushy, grid):
                    visted[newx][newy][d[4]] = True
                    q.put([newx, newy, current[2] + 1, pushx, pushy])

            grid[current[0]][current[1]] = '.'

        return -1
            
    def canReach(self, startx, starty, targetx, targety, grid) -> bool:
        direct = [[0, 1], [0, -1], [-1, 0], [1, 0]]
        rdirect = [[0, -1], [0, 1], [1, 0], [-1, 0]]

        #BFS
        visted = [[False] * len(grid[0]) for i in range(len(grid))]
        q = Queue()
        q.put([startx, starty])
        visted[startx][starty] = True

        while(not q.empty()):
            current = q.get()
            if (current[0] == targetx and current[1] == targety):
                return True
            for d in direct:
                newx = current[0]+d[0]
                newy = current[1]+d[1]
                if (newx >=0 and newy >=0 and newx < len(grid) and newy < len(grid[0])) and \
                   (grid[newx][newy] == '.' or grid[newx][newy] == 'S') and \
                   (not visted[newx][newy]):
                    visted[newx][newy] = True
                    q.put([newx, newy])

        return False

BFS写了两遍,应该还是可以继续优化的。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值