LeetCode--Word Search

Given a 2D board and a word, find if the word exists in the grid.

The word can be constructed from letters of sequentially adjacent cell, where "adjacent" cells are those horizontally or vertically neighboring. The same letter cell may not be used more than once.

For example,
Given board =

[
  ["ABCE"],
  ["SFCS"],
  ["ADEE"]
]
word  =  "ABCCED" , -> returns  true ,
word  =  "SEE" , -> returns  true ,

word = "ABCB", -> returns false.


题目意思是在一个二维表里,可上下左右移动,找出是否存在指定字符串。表中已经匹配过的位置不能再次使用。

思路是回溯加递归,二维表中的某个字符匹配了待匹配的字符串后,下一步考虑表中该位置的上下左右是否匹配字符串的下一个字符。


最开始超时,是因为记录表中已匹配过位置的另一个二维表record的清零方式太低效了,如下

public class Solution {
    public boolean exist(char[][] board, String word) {
        int row = board.length;
        int column = board[0].length;
        if (word.equals(""))
            return true;
        boolean[][] record = new boolean[row][column];
        for (int m = 0; m < row; m++) {
            for (int n = 0; n < column; n++) {
                record[m][n] = false;
            }
        }
        for (int i = 0; i < row; i++) {
            for (int j = 0; j < column; j++) {
                boolean rs = match(board, i, j, 0, word, record);
                if (rs)
                    return rs;
                this.clear(record);
            }
        }
        return false;
    }

    private boolean match(char[][] board, int i, int j, int wordIndex, String word, boolean[][] record) {
        int row = board.length;
        int column = board[0].length;
        if (board[i][j] != word.charAt(wordIndex))
            return false;
        else {
            record[i][j] = true;
            if (wordIndex == word.length() - 1) {
                return board[i][j] == word.charAt(wordIndex);
            } else {
                if (i > 0 && record[i - 1][j] == false) {
                    if (this.match(board, i - 1, j, wordIndex + 1, word, record))
                        return true;
                }
                if (j < column - 1 && record[i][j + 1] == false) {
                    if (this.match(board, i, j + 1, wordIndex + 1, word, record))
                        return true;
                }
                if (i < row - 1 && record[i + 1][j] == false) {
                    if (this.match(board, i + 1, j, wordIndex + 1, word, record))
                        return true;
                }
                if (j > 0 && record[i][j - 1] == false) {
                    if (this.match(board, i, j - 1, wordIndex + 1, word, record))
                        return true;
                }
                return false;
            }
        }
    }

    private void clear(boolean[][] record) {
        int row = record.length;
        int column = record[0].length;
        for (int m = 0; m < row; m++) {
            for (int n = 0; n < column; n++) {
                record[m][n] = false;
            }
        }
    }

}

后来ac用了较为高效的办法,如下

public class Solution {
    public boolean exist(char[][] board, String word) {
        int row = board.length;
        int column = board[0].length;
        if (word.equals(""))
            return true;
        boolean[][] record = new boolean[row][column];
        for (int m = 0; m < row; m++) {
            for (int n = 0; n < column; n++) {
                record[m][n] = false;
            }
        }
        for (int i = 0; i < row; i++) {
            for (int j = 0; j < column; j++) {
                boolean rs = match(board, i, j, 0, word, record);
                if (rs)
                    return rs;
            }
        }
        return false;
    }

    private boolean match(char[][] board, int i, int j, int wordIndex, String word, boolean[][] record) {
        int row = board.length;
        int column = board[0].length;
        if (board[i][j] != word.charAt(wordIndex))
            return false;
        else {
            record[i][j] = true;
            if (wordIndex == word.length() - 1) {
                return board[i][j] == word.charAt(wordIndex);
            } else {
                if (i > 0 && record[i - 1][j] == false) {
                    if (this.match(board, i - 1, j, wordIndex + 1, word, record))
                        return true;
                }
                if (j < column - 1 && record[i][j + 1] == false) {
                    if (this.match(board, i, j + 1, wordIndex + 1, word, record))
                        return true;
                }
                if (i < row - 1 && record[i + 1][j] == false) {
                    if (this.match(board, i + 1, j, wordIndex + 1, word, record))
                        return true;
                }
                if (j > 0 && record[i][j - 1] == false) {
                    if (this.match(board, i, j - 1, wordIndex + 1, word, record))
                        return true;
                }
                record[i][j] = false;
                return false;
            }
        }
    }

}

总结:以后应该注意,能高效的地方尽量高效。在大数据量的测试数据中,很可能会超时。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值