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

相关推荐

  • leetcode191-位1的个数

    原题 编写一个函数,输入是一个无符号整数,返回其二进制表达式中数字位数为 ‘1’ 的个数(也被称为汉明重量)。 示例 1: 输入: 000000000000000000000000…

    算法 2020年4月15日
    0120
  • leetcode322-零钱兑换

    原题 给定不同面额的硬币 coins 和一个总金额 amount。编写一个函数来计算可以凑成总金额所需的最少的硬币个数。如果没有任何一种硬币组合能组成总金额,返回 -1。 示例 1…

    算法 2020年3月8日
    0150
  • leetcode19-删除链表的倒数第N个节点

    原题 给定一个链表,删除链表的倒数第 n 个节点,并且返回链表的头结点。 示例: 给定一个链表: 1->2->3->4->5, 和 n = 2. 当删除了倒数第二个节点后,链表变为…

    算法 2019年12月15日
    090
  • leetcode88-合并两个有序数组

    原题 给定两个有序整数数组 nums1 和 nums2 ,将 nums2 合并到 nums1 中,使得 num1 成为一个有序数组。 说明: 初始化 nums1 和 nums2 的…

    算法 2020年2月23日
    080
  • leetcode119-杨辉三角II

    原题 给定一个非负索引 k,其中 k ≤ 33,返回杨辉三角的第 k 行。在杨辉三角中,每个数是它左上方和右上方的数的和。 示例: 输入: 3 输出: [1,3,3,1] 进阶: …

    2019年11月22日
    0280
  • leetcode69-x的平方根

    原题 实现 int sqrt(int x) 函数。 计算并返回 x 的平方根,其中 x 是非负整数。 由于返回类型是整数,结果只保留整数的部分,小数部分将被舍去。 示例1: 输入:…

    算法 2019年12月30日
    040
  • leetcode410-分割数组的最大值

    原题 给定一个非负整数数组和一个整数 m,你需要将这个数组分成 m 个非空的连续子数组。设计一个算法使得这 m 个子数组各自和的最大值最小。 注意:数组长度 n 满足以下条件: 1…

    算法 2020年1月9日
    0650
  • leetcode56-合并区间

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

    算法 2020年4月16日
    0160
  • 海量数据去重-由BitMap引出的布隆过滤器

    本文参考资源: 那些惊艳的算法们(一)——布隆过滤器_C/C++_xinzhongtianxia的博客-CSDN博客 详解布隆过滤器的原理、使用场景和注意事项 - 简书 概述 昨天…

    2020年2月28日
    01.3K0
  • leetcode297-二叉树的序列化与反序列化

    原题 序列化是将一个数据结构或者对象转换为连续的比特位的操作,进而可以将转换后的数据存储在一个文件或者内存中,同时也可以通过网络传输到另一个计算机环境,采取相反方式重构得到原数据。…

    算法 2020年1月15日
    0110

发表回复

登录后才能评论