【剑指offer题解】leetcode 12,13

12 篇文章 0 订阅
10 篇文章 0 订阅

12. 矩阵中的路径

在这里插入图片描述

思路:dfs回溯+剪枝即可。剪枝的目的是压缩无用的搜索空间,在已知不可能匹配成功的情况下应立即返回,节省非常多的搜索时间。时间复杂度 O ( 3 k M N ) O(3^{k}MN) O(3kMN),因为不能往回找所以是3,空间复杂度 O ( M N ) O(MN) O(MN)

代码:

import numpy as np

class Solution:
    def __init__(self):
        self.go = np.array([[0, -1], [0, 1], [-1, 0], [1, 0]])
        self.tmp = ''
        self.flag = False
        self.tmp_len = 0

    def dfs(self, board, r, c, n1, n2, word, vis):
        if self.flag == True:
            return
        if len(word) == self.tmp_len:
            self.flag = True
            return
        else:
            for i in range(4):
                r1 = r + self.go[i][0]
                c1 = c + self.go[i][1]
                if r1 >= 0 and r1 < n1 and c1 >= 0 and c1 < n2:
                    if vis[r1][c1] == 0 and board[r1][c1] == word[self.tmp_len]:
                        self.tmp += board[r1][c1]
                        vis[r1][c1] = 1
                        self.tmp_len += 1
                        self.dfs(board, r1, c1, n1, n2, word, vis)
                        self.tmp = self.tmp[:-1]
                        vis[r1][c1] = 0
                        self.tmp_len -= 1


    def exist(self, board: List[List[str]], word: str) -> bool:
        n1 = len(board)
        n2 = len(board[0])       
        board = np.array(board)
        vis = np.zeros([n1, n2])

        for i in range(n1):
            for j in range(n2):
                if board[i][j] == word[0]:
                    self.tmp += board[i][j]
                    vis[i][j] = 1
                    self.tmp_len += 1
                    self.dfs(board, i, j, n1, n2, word, vis)
                    self.tmp = self.tmp[:-1]
                    vis[i][j] = 0
                    self.tmp_len -= 1
                    if self.flag == True:
                        return True

        return False

这个代码性能一般般,还请大佬多多指点~

13. 机器人的运动范围

在这里插入图片描述
错误思路:这个题非常具有迷惑性,拿到以后首先会想,不就是把整个格子遍历一遍嘛,然后统计一下满足条件的格子个数就好了。但是,假设现在的维度是1*10,界限k=9,那么此时点(1,9)是不满足条件的,而(1,10)满足条件;但是如果不经过(1,9),机器人也无法达到(1,10),因此这种思路由于忽略了障碍格子的影响,会导致多计数。

正确思路:其实这是一个搜索问题,dfs或bfs均可,这样遇到障碍格子就不会再无脑地往下搜索了,下面给出dfs的代码。

代码:

import numpy as np

class Solution:
    def calSum(self, r, c):
        ans = 0
        while r > 0:
            ans += r % 10
            r = int(r/10)
        while c > 0:
            ans += c % 10
            c = int(c/10)
        return ans

    def dfs(self, r, c, m, n, k, vis, go):
        if self.calSum(r, c) <= k:
            vis[r][c] = 1
            for i in range(4):
                r1 = r+go[i][0]
                c1 = c+go[i][1]
                if r1 >= 0 and r1 < m and c1 >= 0 and c1 < n:
                    if vis[r1][c1] == 0:
                        self.dfs(r1, c1, m, n, k, vis, go)
        else:
            vis[r][c] = -1

    def movingCount(self, m: int, n: int, k: int) -> int:
        vis = np.zeros([m, n])
        go = np.array([[0, 1], [0, -1], [1, 0], [-1, 0]])
        self.dfs(0, 0, m, n, k, vis, go)
        return int(np.sum(vis==1))
        
  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值