Skip to content
Rain Hu's Workspace
Go back

[LeetCode] 79. Word Search

Rain Hu

79. Word Search


一、題目

Given an m x n grid of characters board and a string word, return true if word exists in the grid.
The word can be constructed from letters of sequentially adjacent cells, where adjacent cells are horizontally or vertically neighboring. The same letter cell may not be used more than once.

Example 1:

Example 2:

Example 3:

Constraints:

Follow up: Could you use search pruning to make your solution faster with a larger board?


二、分析

三、解題

1. Backtracking

class Board {
private:
    vector<vector<char>> board;
    int m, n;
    int cnt[128];

    // 用於上、下、左、右
    int dirc[4][2] = {{1,0},{0,1},{-1,0},{0,-1}};

    // 用於剪枝1與剪枝2,在進行算法前,檢查其是否可能為錯,時間複雜度為 O(1),所以可以大大降低耗時。
    bool isWordNumValid(string& word) {
        if (word.length() > m * n) return false;    // 剪枝1
        int charNum[128] = {0};
        for (char c : word) charNum[c]++;
        for (int i = 0; i < 128; i++) {
            if (charNum[i] > cnt[i]) return false;  // 剪枝2
        }
        return true;
    }

    void reverseIfNeeded(string& word) {
        int left = word.find_first_not_of(word[0]);     // 左邊重複
        int right = word.length() - word.find_last_not_of(word[word.length()-1]);       // 右邊重複
        if (left > right) reverse(word.begin(), word.end());    // 左邊重複較長,則翻轉字串
    }

    bool backtrack(string& word, int row, int col, int i) {
        if (i == word.length()) return true;        // 到達終止條件,回傳 true
        if (row < 0 || col < 0 || row >= m || col >= n || board[row][col] != word[i]) return false;     // out of bound 或不符合
        char tmp = board[row][col];     // 記錄原本的格子
        board[row][col] = '#';          // 用 '#' 代表 visited,省去另外創一個 visited 來記錄是否拜訪過
        for (const auto& d : dirc)
            if (backtrack(word, row+d[0], col+d[1], i+1)) {
                // board[row][col] = tmp;      // 記得將 backtrack 更動的部分走完,以免影響其它組解
                return true;
            }
        board[row][col] = tmp;          // 還原格子
        return false;
    }
    
public:
    Board(vector<vector<char>>& board_) {
        this->board = board_;
        this->m = board_.size();
        this->n = board_[0].size();
        memset(cnt, 0, sizeof(cnt));
        for (const auto& row : board) {
            for (char c : row) {
                cnt[c]++;
            }
        }
    }
    bool search(string& word) {
        for (int i = 0; i < m; i++) {
            for (int j = 0; j < n; j++) {
                if (!isWordNumValid(word)) return false;
                reverseIfNeeded(word);
                if (backtrack(word, i, j, 0)) return true;
            }
        }
        return false;
    }
};
class Solution {
public:
    bool exist(vector<vector<char>>& board, string word) {
        Board b(board);
        return b.search(word);
    }
};

回目錄 Catalog


Share this post on:

Previous
[ML] 機器學習與統計學
Next
[LeetCode] 212. Word Search II