LeetCode Word Search

typedef struct tagCharUsed {
    int i;
    int j;
    bool used;
    tagCharUsed(int _i, int _j, bool _used = false): i(_i), j(_j), used(_used){};
} CharUsed;

class Solution {
public:
    bool exist(vector<vector<char> > &board, string word) {
        vector<CharUsed> table[256];
        for (int i=0; i<board.size(); i++) {
            for (int j=0; j<board[i].size(); j++) {
                table[board[i][j]].push_back(CharUsed(i, j));
            }
        }
        return dfs(board, table, word, 0, NULL);
    }
    
    bool dfs(vector<vector<char> >& board, vector<CharUsed>* table, string word, int pos, CharUsed* last) {
        if (pos >= word.size()) return true;
        char ch = word[pos];
        vector<CharUsed>& chars = table[ch];
        
        for (int i=0; i<chars.size(); i++) {
            CharUsed& cur = chars[i];
            if (cur.used || (last != NULL && abs(last->i - cur.i) + abs(last->j - cur.j) > 1)) continue;
            cur.used = true;
            if (dfs(board, table, word, pos + 1, &cur)) return true;
            cur.used = false;
        }
        return false;
    }
};

很容易想到用dfs搜索,但是一开始感觉dfs每次要把整个表扫一遍是不是太费时了(当时认为对于一个表会查询多次)?于是转变一下思路,先统计一下board中出现的字母与位置,然后根据提供的字符串进行dfs,原以为这样会快一点,然而这样是简单的直接使用dfs的好几倍,我想可能是仅查询一次的原因,如果对于一个board多次查询的话,用于统计的时间占比就小了。后来做了一下实验,在单个board多次查询下,两者速度是一致的,不过后来又测了数据发现变得更差了,哎。。。,因为后者按序查到的字母不一定是邻接的,而且单单通过设置used标记变量这样的方式是低效的,因为每次都要扫过前面已经被设置过的元素,这可以通过使用链表的形式解决,不过这样越来越复杂了。

还是贴上直接dfs的代码,这里把条件判断都提前了,四个方向的遍历也可以放到一个循环里。

class Solution {
private:
    int cols;
    int rows;
    int len;
public:
    bool exist(vector<vector<char> > &board, string word) {
        if (word.size() == 0) return true;
        rows = board.size();
        if (rows == 0) return false;
        cols = board[0].size();
        len  = word.length();
        char first = word[0];
        for (int i=0; i<rows; i++) {
            vector<char>& row = board[i];
            for (int j=0; j<cols; j++) {
                if (row[j] == first && dfs(board, word, 0, i, j)) return true;
            }
        }
        return false;
    }
    bool dfs(vector<vector<char> >& board, string& word, int pos, int i, int j) {
        char ch = word[pos];
        if (pos == len - 1) return true;
        char next = word[pos + 1];
        bool ret;
        if (j + 1 < cols && board[i][j + 1] == next) {
            board[i][j] = 0;
            ret = dfs(board, word, pos + 1, i, j + 1);
            board[i][j] = ch;
            if (ret) return true;
        }
        if (j - 1 >= 0 && board[i][j - 1] == next) {
            board[i][j] = 0;
            ret = dfs(board, word, pos + 1, i, j - 1);
            board[i][j] = ch;
            if (ret) return true;
        }
        if (i + 1 < rows && board[i+1][j] == next) {
            board[i][j] = 0;
            ret = dfs(board, word, pos + 1, i + 1, j);
            board[i][j] = ch;
            if (ret) return true;
        }
        
        if (i - 1 >= 0 && board[i-1][j] == next) { 
            board[i][j] = 0;
            ret = dfs(board, word, pos + 1, i - 1, j);
            board[i][j] = ch;
            if (ret) return true;
        }
        return false;
    }
};

 

参考:

zhuli哥的题解 http://www.cnblogs.com/zhuli19901106/p/3570506.html

第二轮:

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.

犯了几个错误,看来要一次写出bug free的代码还是不太容易,挺怕这样的要求。

class Solution {
public:
    bool exist(vector<vector<char> > &board, string word) {
        if (word.size() == 0) {
            return true;
        }
        int ylen = board.size();
        if (ylen < 1) {
            return false;
        }
        int xlen = board[0].size();
        if (xlen < 1) {
            return false;
        }
        if (xlen * ylen < word.size()) {
            return false;
        }
        vector<bool> m(xlen*ylen, false);
        for (int i=0; i<ylen; i++) {
            for (int j=0; j<xlen; j++) {
                if (dfs(board, word, j, i, 0, m)) {
                    return true;
                }
            }
        }
        return false;
    }
    
    bool dfs(vector<vector<char> > &board, string& word, int x, int y, int pos, vector<bool>& m) {
        if (pos == word.size()) {
            return true;
        }
        int ylen = board.size();
        int xlen = board[0].size();
        
        if (x >= xlen || y >= ylen || x < 0 || y < 0) {
            return false;
        }
        
        if (board[y][x] != word[pos]) {
            return false;
        }
        
        if (m[y*xlen + x]) {
            return false;
        }
        
        pos++;
        m[y*xlen + x] = true;
        bool res = dfs(board, word, x + 1, y, pos, m) 
                || dfs(board, word, x, y + 1, pos, m)
                || dfs(board, word, x - 1, y, pos, m)
                || dfs(board, word, x, y - 1, pos, m);
        m[y*xlen + x] = false;
        return res;
    }
};

 

posted @ 2014-03-20 15:23  卖程序的小歪  阅读(206)  评论(0编辑  收藏  举报