最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • 在矩阵中寻找一个字符串应该怎么找?|刷题打卡

    正文概述 掘金(灬青芒灬)   2021-03-11   515

    在一个矩阵中寻找一个固定的字符串,你会怎么做呢?

    原题链接剑指 Offer 12. 矩阵中的路径

    相同解法主站链接:79. 单词搜索

    一、先看题

    请设计一个函数,用来判断在一个矩阵中是否存在一条包含某字符串所有字符的路径。路径可以从矩阵中的任意一格开始,每一步可以在矩阵中向左、右、上、下移动一格。如果一条路径经过了矩阵的某一格,那么该路径不能再次进入该格子。例如,在下面的3×4的矩阵中包含一条字符串“bfce”的路径(路径中的字母已标出)。

    [["a","b","c","e"],

    ["s","f","c","s"],

    ["a","d","e","e"]]

    示例:

    示例2:

    提示:

    • 1<=board.length<=2001 <= board.length <= 2001<=board.length<=200
    • 1<=board[i].length<=2001 <= board[i].length <= 2001<=board[i].length<=200

    二、整理思路

    题目包含了不少信息和限制,我们先一点点分析,理清思路。

    第一步:

    确认输入输出:

    输入:一个二维数组;输出:布尔值。

    第二步

    怎么处理输入才能得到输出?

    在题干中的解释来看,其实就是找到一条有序的路径,而且这条路径经过每个格子时都是类似的判断条件,除此之外,这条路径不能走相同的格子。

    从这两点分析,很容易就能想到,这个题应该能用递归来处理。并且需要某种方法来记录已经走过的格子的状态。

    因此,得到了下面的算法:

    /**
     * @param {character[][]} board
     * @param {string} word
     * @return {boolean}
     */
    function find(board, wordArr, status, i, j, idx) {
        //考虑边界情况以及字符对比和重复
        if (i < 0 || j < 0 || i > board.length - 1 || j > board[0].length - 1 || board[i][j] != wordArr[idx] || status[i][j] == 0) return false
        //成功查找到最后一个字符
        if (idx == wordArr.length-1) return true
        status[i][j] = 0
        //上下左右依次查找
        res = find(board, wordArr, status, i + 1, j, idx + 1) || find(board, wordArr, status, i, j + 1, idx + 1) || find(board, wordArr, status, i - 1, j, idx + 1) || find(board, wordArr, status, i, j - 1, idx + 1)
        //只有没找到结果才会走这里,因此将字符状态复原
        status[i][j] = 1
        return res
    }
    
    var exist = function (board, word) {
        let status = []
        //值得注意的是,当fill中填充的值为引用类型时,
        //修改一个填充单位的值会修改所有的填充单位。
        //因此这里改用for循环来填充
        for(let i=0;i<board.length;i++){
            status.push(new Array(board[0].length).fill(1))
        }
        let wordArr = Array.from(word)
        for(let i=0;i<board.length;i++){
            for(let j=0;j<board[0].length;j++){
                if(find(board,wordArr,status,i,j,0)) return true
            }
        }
        return false
    };
    

    在自己解决的过程中,最难的就是理清DFS思路,false的情况是比较显眼的,但是返回true的条件当时却一时未能想到。还有一个点就是状态复原这个操作,最初一直没想好怎么处理,后来参考了题解,才想明白,无论他返回的是true或者false,我们统一在判断完之后对他进行复原就好了,这样下级的判断就不会影响到上级。

    题解中还有一种能减少空间复杂度的方式,贴在下面供大家参考:

    /**
     * @param {character[][]} board
     * @param {string} word
     * @return {boolean}
     */
    function find(board, wordArr, i, j, idx) {
        //考虑边界情况以及字符对比和重复
        if (i < 0 || j < 0 || i > board.length - 1 || j > board[0].length - 1 || board[i][j] != wordArr[idx]) return false
        //成功查找到最后一个字符
        if (idx == wordArr.length-1) return true
        //直接修改原数组为空字符
        board[i][j] = '\0'
        //上下左右依次查找
        res = find(board, wordArr, i + 1, j, idx + 1) || find(board, wordArr, i, j + 1, idx + 1) || find(board, wordArr, i - 1, j, idx + 1) || find(board, wordArr, i, j - 1, idx + 1)
        //只有没找到结果才会走这里,因此将字符状态复原
        //将空字符复原
        board[i][j] = wordArr[idx]
        return res
    }
    
    var exist = function (board, word) {
        let wordArr = Array.from(word)
        for(let i=0;i<board.length;i++){
            for(let j=0;j<board[0].length;j++){
                if(find(board,wordArr,i,j,0)) return true
            }
        }
        return false
    };
    

    这个方法通过暂时性的修改原数组,减少了状态变量的空间消耗。但是在实际测试中,对数组的字符进行频繁修改反而增加了一些内存消耗,时间上总体来说要快一些,可能是因为减少了创建状态变量的时间。

    三、总结

    当题目复杂的时候,我们可以把题目中给出的条件分析一遍,找到边界条件,然后再根据恰当的思路进行算法分析,将复杂的题目简单化从而归纳到熟悉的体系中才是解题的正确思路。

    一起加油吧!

    在矩阵中寻找一个字符串应该怎么找?|刷题打卡

    本文正在参与「掘金 2021 春招闯关活动」, 点击查看 活动详情


    起源地下载网 » 在矩阵中寻找一个字符串应该怎么找?|刷题打卡

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元