leetcode79-单词搜索

原题

给定一个二维网格和一个单词,找出该单词是否存在于网格中。

单词必须按照字母顺序,通过相邻的单元格内的字母构成,其中“相邻”单元格是那些水平相邻或垂直相邻的单元格。同一个单元格内的字母不允许被重复使用。

示例:

board =
[
  ['A','B','C','E'],
  ['S','F','C','S'],
  ['A','D','E','E']
]

给定 word = "ABCCED", 返回 true
给定 word = "SEE", 返回 true
给定 word = "ABCB", 返回 false

 

提示:

  • boardword 中只包含大写和小写英文字母。
  • 1 <= board.length <= 200
  • 1 <= board[i].length <= 200
  • 1 <= word.length <= 10^3

解法

思想

因为同一个位置的字符不能用两次,得标记,dfs回溯的时候必须把标记清除。

代码

class Solution {
    char[][] board;
    boolean[][] visited;
    public boolean exist(char[][] board, String word) {
        this.board = board;
        for(int i = 0;i<board.length;i++){
            for(int j = 0;j<board[0].length;j++){
                visited = new boolean[board.length][board[0].length];
                if(dfs(i,j,word)) return true;
            }
        }
        return false;
    }

    public boolean dfs(int x,int y,String word){
        if(word.length()==1){
            if(word.charAt(0)==board[x][y]) return true;
        } 
        if(word.charAt(0)!=board[x][y]) return false;
        visited[x][y] = true;
        boolean ans = false;
        //向上
        if(x-1>=0 && !visited[x-1][y]) ans = ans||dfs(x-1,y,word.substring(1));
        //向下
        if(x+1<board.length && !visited[x+1][y]) ans = ans||dfs(x+1,y,word.substring(1));
        //向左
        if(y-1>=0 && !visited[x][y-1]) ans = ans||dfs(x,y-1,word.substring(1));
        //向右
        if(y+1<board[0].length && !visited[x][y+1]) ans = ans||dfs(x,y+1,word.substring(1));
        //清除标记
        if(ans == false) visited[x][y] = false;
        return ans;
    } 
}

下面是利用短路或剪枝后的版本,按理说更快,leetcode测试也差不多:

class Solution {
    char[][] board;
    boolean[][] visited;
    public boolean exist(char[][] board, String word) {
        this.board = board;
        for(int i = 0;i<board.length;i++){
            for(int j = 0;j<board[0].length;j++){
                visited = new boolean[board.length][board[0].length];
                if(dfs(i,j,word)) return true;
            }
        }
        return false;
    }

    public boolean dfs(int x,int y,String word){
        if(word.length()==1){
            if(word.charAt(0)==board[x][y]) return true;
        } 
        if(word.charAt(0)!=board[x][y]) return false;
        visited[x][y] = true;
        //向上
        if(x-1>=0 && !visited[x-1][y]) if(dfs(x-1,y,word.substring(1))) return true;
        //向下
        if(x+1<board.length && !visited[x+1][y]) if(dfs(x+1,y,word.substring(1))) return true;
        //向左
        if(y-1>=0 && !visited[x][y-1]) if(dfs(x,y-1,word.substring(1))) return true;
        //向右
        if(y+1<board[0].length && !visited[x][y+1]) if(dfs(x,y+1,word.substring(1))) return true;
        //清除标记
        visited[x][y] = false;
        return false;
    } 
}

原创文章,作者:彭晨涛,如若转载,请注明出处:https://www.codetool.top/article/leetcode79-%e5%8d%95%e8%af%8d%e6%90%9c%e7%b4%a2/

(0)
彭晨涛彭晨涛管理者
上一篇 2020年4月11日 19:46
下一篇 2020年4月12日 16:20

相关推荐

  • leetcode20-有效的括号

    原题 给定一个只包括 '(',')','{','}','[',']' 的字符串,判断字符串是否有效。 有效字符串需满足: 左括号必须用相同类型的右括号闭合。 左括号必须以正确的顺序…

    算法 2019年12月11日
    0210
  • leetcode57-插入区间

    原题 给出一个无重叠的 ,按照区间起始端点排序的区间列表。 在列表中插入一个新的区间,你需要确保列表中的区间仍然有序且不重叠(如果有必要的话,可以合并区间)。 示例 1: 输入: …

    算法 2020年5月12日
    0280
  • leetcode17-电话号码的字母组合

    原题 给定一个仅包含数字 2-9 的字符串,返回所有它能表示的字母组合。 给出数字到字母的映射如下(与电话按键相同)。注意 1 不对应任何字母。 示例: 输入: "23" 输出: …

    2020年5月3日
    0130
  • leetcode540-有序数组中的单一元素

    原题 给定一个只包含整数的有序数组,每个元素都会出现两次,唯有一个数只会出现一次,找出这个数。 示例1: 输入: [1,1,2,3,3,4,4,8,8] 输出: 2 示例2: 输入…

    2020年2月25日
    0700
  • leetcode429-N叉树的层序遍历

    原题 给定一个 N 叉树,返回其节点值的层序遍历。 (即从左到右,逐层遍历)。 例如,给定一个 3叉树 : 返回其层序遍历: [ [1], [3,2,4], [5,6] ] 说明:…

    2020年1月20日
    0140
  • leetcode1115-交替打印FooBar

    原题 我们提供一个类: class FooBar { public void foo() {     for (int i = 0; i < n; i++) {       …

    算法 2020年2月2日
    0180
  • leetcode1071-字符串的最大公因子

    原题 对于字符串 S 和 T,只有在 S = T + ... + T(T 与自身连接 1 次或多次)时,我们才认定 “T 能除尽 S”。 返回最长字符串 X,要求满足 X 能除尽 …

    算法 2020年3月12日
    0250
  • leetcode160-相交链表

    原题 编写一个程序,找到两个单链表相交的起始节点。 如下面的两个链表: 在节点 c1 开始相交。 示例 1: 输入: intersectVal = 8, listA = [4,1,…

    2019年12月14日
    090
  • leetcode443-压缩字符串

    原题 给定一组字符,使用原地算法将其压缩。 压缩后的长度必须始终小于或等于原数组长度。 数组的每个元素应该是长度为1 的字符(不是 int 整数类型)。 在完成原地修改输入数组后,…

    算法 2020年5月28日
    070
  • leetcode56-合并区间

    原题 给出一个区间的集合,请合并所有重叠的区间。 示例 1: 输入: [[1,3],[2,6],[8,10],[15,18]] 输出: [[1,6],[8,10],[15,18]]…

    算法 2020年4月16日
    0160

发表回复

登录后才能评论