美文网首页
算法挑战100天 - Nine(mid)

算法挑战100天 - Nine(mid)

作者: holmes000 | 来源:发表于2020-09-27 16:11 被阅读0次

类别:数组

题目:https://leetcode-cn.com/problems/word-search/

我的解:时间O(MN⋅4^L) 空间O(MN)

  private int m;
    private int n;
    private boolean[][] marked;
    private char[][] board;
    private String word;

    boolean exist(char[][] board, String word) {
        m = board.length;
        n = board[0].length;
        if (m == 0 || n == 0) {
            return false;
        }
        marked = new boolean[m][n];
        this.word = word;
        this.board = board;
        for (int i = 0; i < board.length; i++) {
            for (int j = 0; j < board[i].length; j++) {
                if (this.dfs(i, j, 0)) {
                    return true;
                }
            }
        }
        return false;
    }

    boolean dfs(int i, int j, int start) {
        if (start == word.length() - 1 && board[i][j] == word.charAt(start)) {
            return true;
        }
        if (board[i][j] == word.charAt(start)) {
            for (int k = 0; k < 4; k++) {
              //便于回溯打标
                marked[i][j] = true;
                int newI = i;
                int newJ = j;
                switch (k) {
                    //右
                    case 0:
                        newI = i + 1;
                        break;
                    //下
                    case 1:
                        newJ = j + 1;
                        break;
                    //左
                    case 2:
                        newI = i - 1;
                        break;
                    //上
                    case 3:
                        newJ = j - 1;
                }
                if (newI >= 0 && newJ >= 0
                        && newI < m && newJ < n
                        && !marked[newI][newJ]
                        && dfs(newI, newJ, start + 1)) {
                    return true;
                }
                marked[i][j] = false;
            }

        }
        return false;
    }

最优解:时间O(MN⋅(4~1)^L) 空间O(MN)

public boolean exist(char[][] board, String word) {
    char[] words = word.toCharArray();
    for (int i = 0; i < board.length; i++) {
        for (int j = 0; j < board[0].length; j++) {
            //从[i,j]这个坐标开始查找
            if (dfs(board, words, i, j, 0))
                return true;
        }
    }
    return false;
}

boolean dfs(char[][] board, char[] word, int i, int j, int index) {
    //边界的判断,如果越界直接返回false。index表示的是查找到字符串word的第几个字符,
    //如果这个字符不等于board[i][j],说明验证这个坐标路径是走不通的,直接返回false
    if (i >= board.length || i < 0 || j >= board[0].length || j < 0 || board[i][j] != word[index])
        return false;
    //如果word的每个字符都查找完了,直接返回true
    if (index == word.length - 1)
        return true;
    //把当前坐标的值保存下来,为了在最后复原
    char tmp = board[i][j];
    //然后修改当前坐标的值
    board[i][j] = '.';
    //走递归,沿着当前坐标的上下左右4个方向查找
    boolean res = dfs(board, word, i + 1, j, index + 1) || dfs(board, word, i - 1, j, index + 1) ||
            dfs(board, word, i, j + 1, index + 1) || dfs(board, word, i, j - 1, index + 1);
    //递归之后再把当前的坐标复原
    board[i][j] = tmp;
    return res;
}

关键点:

1:回溯
2:深度优先搜索dfs

差异点:

一 最优解利用了卫语句,先置过滤掉无需处理数据;
二 标记是用特殊值.,未新增数据结构;
三 4方向求解 利用|| 达到剪枝效果;

可借鉴的还有他求解思路,先有大体框架,再去考虑细节;很重要;

我们看到他是从矩形中的一个点开始往他的上下左右四个方向查找,这个点可以是矩形中的任何一个点,所以代码的大致轮廓我们应该能写出来,就是遍历矩形所有的点,然后从这个点开始往他的4个方向走,因为是二维数组,所以有两个for循环,代码如下

public boolean exist(char[][] board, String word) {
    char[] words = word.toCharArray();
    for (int i = 0; i < board.length; i++) {
        for (int j = 0; j < board[0].length; j++) {
            //从[i,j]这个坐标开始查找
            if (dfs(board, words, i, j, 0))
                return true;
        }
    }
    return false;
}

这里关键代码是dfs这个函数,因为每一个点我们都可以往他的4个方向查找,所以我们可以把它想象为一棵4叉树,就是每个节点有4个子节点,而树的遍历我们最容易想到的就是递归,我们来大概看一下

boolean dfs(char[][] board, char[] word, int i, int j, int index) {
    if (边界条件的判断) {
        return;
    }

    一些逻辑处理

    boolean res;
    //往右
    res = dfs(board, word, i + 1, j, index + 1)
    //往左
    res |= dfs(board, word, i - 1, j, index + 1)
    //往下
    res |= dfs(board, word, i, j + 1, index + 1)
    //往上
    res |= dfs(board, word, i, j - 1, index + 1)
    //上面4个方向,只要有一个能查找到,就返回true;
    return res;
}

相关文章

  • 算法挑战100天 - Nine(mid)

    类别:数组 题目:https://leetcode-cn.com/problems/word-search/[ht...

  • 算法挑战100天 - six(mid)

    类别:数组 题目:https://leetcode-cn.com/problems/sub-sort-lcci/ ...

  • 算法挑战100天-Ten(mid)

    类别:数组 题目:https://leetcode-cn.com/problems/longest-continu...

  • 数据结构实验——折半查找

    前子表查找:high=mid-1;后子表查找:low=mid+1;算法分析:1.确定查找有序序列a,置查找区间初值...

  • Nine

    After reading the story, the former classmates were thoug...

  • Nine

    都说90后的孩子容易早恋,我想我还是跟上了时尚的“前沿”。高一的时候才16岁,我居然恋爱了,现在想来那时候还真是天...

  • nine

    老话说的好,美好的时光总是短暂的,一恍惚的时间。就迎来了我“所期待的日子”—期中考试。我估计,这应该是每一个职校生...

  • nine

    周一的体育课之后,便是同学们高中的第一节英语课。 张珊珊从小学开始英语成绩就名列前茅,初中当了三年的英语课...

  • Nine

    Ninei

  • nine

    再次睁开眼睛时冉遗发现现在。。。眼前一片绿草如茵,蝴蝶翩飞,远处还有袅袅炊烟“我们?” “啊,你那几个同学误打误撞...

网友评论

      本文标题:算法挑战100天 - Nine(mid)

      本文链接:https://www.haomeiwen.com/subject/cnfluktx.html