天天看點

阿裡面試真題題解:單詞搜尋 II

給出一個由小寫字母組成的矩陣和一個字典。

找出所有同時在字典和矩陣中出現的單詞。

一個單詞可以從矩陣中的任意位置開始,可以向左/右/上/下四個相鄰方向移動。

一個字母在一個單詞中隻能被使用一次。且字典中不存在重複單詞。

線上評測位址:

領扣刷題官網 樣例 1:

輸入:["doaf","agai","dcan"],["dog","dad","dgdg","can","again"]
輸出:["again","can","dad","dog"]
解釋:
  d o a f
  a g a i
  d c a n
矩陣中查找,傳回 ["again","can","dad","dog"]。           

樣例 2:

輸入:["a"],["b"]
輸出:[]
解釋:
 a
矩陣中查找,傳回 []。           

題解

使用 HashMap 的版本。 将所有的單詞的 Prefix 都加入 HashMap 中。HashMap 的 value 使用者判斷這是一個 prefix 還是一個 word。 如果是 prefix 就是 false,如果是 word 就是 true.

public class Solution {
    public static int[] dx = {0, 1, -1, 0};
    public static int[] dy = {1, 0, 0, -1};
    /**     * @param board: A list of lists of character     * @param words: A list of string     * @return: A list of string     */
    public List<String> wordSearchII(char[][] board, List<String> words) {
        if (board == null || board.length == 0) {
            return new ArrayList<>();
        }
        if (board[0] == null || board[0].length == 0) {
            return new ArrayList<>();
        }
        
        boolean[][] visited = new boolean[board.length][board[0].length];
        Map<String, Boolean> prefixIsWord = getPrefixSet(words);
        Set<String> wordSet = new HashSet<>();
        
        for (int i = 0; i < board.length; i++) {
            for (int j = 0; j < board[i].length; j++) {
                visited[i][j] = true;
                dfs(board, visited, i, j, String.valueOf(board[i][j]), prefixIsWord, wordSet);
                visited[i][j] = false;
            }
        }
        
        return new ArrayList<String>(wordSet);
    }
    
    private Map<String, Boolean> getPrefixSet(List<String> words) {
        Map<String, Boolean> prefixIsWord = new HashMap<>();
        for (String word : words) {
            for (int i = 0; i < word.length() - 1; i++) {
                String prefix = word.substring(0, i + 1);
                if (!prefixIsWord.containsKey(prefix)) {
                    prefixIsWord.put(prefix, false);
                }
            }
            prefixIsWord.put(word, true);
        }
        
        return prefixIsWord;
    }
    
    private void dfs(char[][] board,
                     boolean[][] visited,
                     int x,
                     int y,
                     String word,
                     Map<String, Boolean> prefixIsWord,
                     Set<String> wordSet) {
        if (!prefixIsWord.containsKey(word)) {
            return;
        }
        
        if (prefixIsWord.get(word)) {
            wordSet.add(word);
        }
        
        for (int i = 0; i < 4; i++) {
            int adjX = x + dx[i];
            int adjY = y + dy[i];
            
            if (!inside(board, adjX, adjY) || visited[adjX][adjY]) {
                continue;
            }
            
            visited[adjX][adjY] = true;
            dfs(board, visited, adjX, adjY, word + board[adjX][adjY], prefixIsWord, wordSet);
            visited[adjX][adjY] = false;
        }
    }
    
    private boolean inside(char[][] board, int x, int y) {
        return x >= 0 && x < board.length && y >= 0 && y < board[0].length;
    }
}           

更多題解參考:

九章官網Solution

繼續閱讀