leetcode刷题笔记——单词搜索

题目描述:

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

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

示例:

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

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

解题思路:

回溯法和深度优先搜索(dfs)

第一版代码:

第一版是自己写的,想到了回溯法,但是没有很想明白dfs。具体代码如下,思想是先遍历二维数组,找到word中的第一个字母所在位置,然后从该位置起,试探上、下、左、右四个位置的字母是否与word中的下一个字母匹配,若是,则将该位置作为新的起始位置,word字母坐标向后移一位,进行递归,并用flag[i](0<=i<=3)来记录该路径是否与word匹配。

但这种思路会造成超时,因为它会将二维数组的所有的len(word)长度的路径遍历一遍,当数组规模过大并且word长度较长时,会出现用时过长的情况。所以应该走一条路,如果这条路与word匹配了,则立即返回true,不需要再考虑其他的路径了。

class Solution {
    public boolean exist(char[][] board, String word) {
        if(board == null || board.length == 0)
            return false;

        for(int i=0; i<board.length; i++){
            for (int j=0; j<board[0].length; j++){
                if(word.charAt(0) == board[i][j]){
       
int[][] mark = new int[board.length][board[0].length]; mark[i][j] = 1; if(func(board, word, 1, i, j, mark)) return true; } } } return false; } public boolean func(char[][] board, String word, int pos, int row, int col, int[][] mark){ if(pos == word.length()) return true; boolean[] flag = new boolean[4]; if(row > 0 && mark[row-1][col] == 0){ if(board[row-1][col] == word.charAt(pos)){ mark[row-1][col] = 1; flag[0] = func(board, word, pos+1, row-1, col, mark); mark[row-1][col] = 0; } } if (row < board.length-1 && mark[row+1][col] == 0) { if (board[row + 1][col] == word.charAt(pos)){ mark[row+1][col] = 1; flag[1] = func(board, word, pos+1, row+1, col, mark); mark[row+1][col] = 0; } } if(col > 0 && mark[row][col-1] == 0) { if (board[row][col - 1] == word.charAt(pos)){ mark[row][col-1] = 1; flag[2] = func(board, word, pos+1, row, col-1, mark); mark[row][col-1] = 0; } } if(col < board[0].length-1 && mark[row][col+1] == 0){ if(board[row][col+1] == word.charAt(pos)){ mark[row][col+1] = 1; flag[3] = func(board, word, pos+1, row, col+1, mark); mark[row][col+1] = 0; } } if(flag[0] || flag[1] || flag[2] || flag[3]) return true; return false; } }

第二版代码:

是看了题解之后在第一版代码上面改的,加入了dfs的思想,去掉了flag[]这个标志位,如果这条路径与word匹配,则直接返回

public boolean exist(char[][] board, String word) {
        if(board == null || board.length == 0)
            return false;

        for(int i=0; i<board.length; i++){
            for (int j=0; j<board[0].length; j++){
                if(word.charAt(0) == board[i][j]){
                    //记录该位置是否已经通过
                    int[][] mark = new int[board.length][board[0].length];
                    mark[i][j] = 1;
                    if(func(board, word, 1, i, j, mark))
                        return true;
                }
            }
        }
        return false;
    }

    public boolean func(char[][] board, String word, int pos, int row, int col, int[][] mark){
        if(pos == word.length()) return true;
        boolean[] flag = new boolean[4];
        if(row > 0 && mark[row-1][col] == 0){
            if(board[row-1][col] == word.charAt(pos)){
                mark[row-1][col] = 1;
                //递归
                if(func(board, word, pos+1, row-1, col, mark))
                    return true;
                //回溯
                mark[row-1][col] = 0;
            }

        }
        if (row < board.length-1 && mark[row+1][col] == 0) {
            if (board[row + 1][col] == word.charAt(pos)){
                mark[row+1][col] = 1;
                if(func(board, word, pos+1, row+1, col, mark))
                    return true;
                mark[row+1][col] = 0;
            }

        }
        if(col > 0 && mark[row][col-1] == 0) {
            if (board[row][col - 1] == word.charAt(pos)){
                mark[row][col-1] = 1;
                if(func(board, word, pos+1, row, col-1, mark))
                    return true;
                mark[row][col-1] = 0;
            }

        }
        if(col < board[0].length-1 && mark[row][col+1] == 0){
            if(board[row][col+1] == word.charAt(pos)){
                mark[row][col+1] = 1;
                if(func(board, word, pos+1, row, col+1, mark))
                    return true;
                mark[row][col+1] = 0;
            }

        }
        return false;
    }

猜你喜欢

转载自www.cnblogs.com/yingying7/p/11331066.html
今日推荐