212. Word Search II

안창범·2023년 9월 10일
0

LeetCode Top Interview 150

목록 보기
25/27

문제

https://leetcode.com/problems/word-search-ii/description/?envType=study-plan-v2&envId=top-interview-150

해결 방법

  • 처음에는 words의 단어들을 하나씩 bfs를 돌려 생성할 수 있는지 체크하는 방식으로 시도했음 => words가 최대 30,000개 입력되기 때문에 시간 초과가 발생함
  • 따라서 먼저 board에서 만들 수 있는 단어를 dfs를 이용하여 Trie에 삽입 후 words의 단어들을 순회하며 Trie에서 search하는 방식으로 해결
    • 이 때, 시간을 줄이기 위해 words의 단어들을 먼저 조회하며 단어의 길이(최대 10)가 존재한다면 dfs 실행
    • 길이가 10인 단어가 없는데 10짜리 단어들을 모두 Trie에 삽입할 필요가 없기 때문

코드

class Solution {

    private static Trie trie;
    private static final int[] row = new int[]{0, 0, 1, -1};
    private static final int[] col = new int[]{1, -1, 0, 0};

    public List<String> findWords(char[][] board, String[] words) {
        trie = new Trie();
        int m = board.length;
        int n = board[0].length;

        boolean[] lenCheck = new boolean[11];
        int cnt = 0;
        for (String word : words) {
            if (lenCheck[word.length()] == false) {
                lenCheck[word.length()] = true;
                makeTrie(word.length(), m, n, board);
                cnt ++;
            }
            if (cnt == 10) break;
        }

        List<String> answer = new ArrayList<>();
        for (String word : words) {
            if (trie.search(word)) {
                answer.add(word);
            }
        }

        return answer;
    }

    private void makeTrie(int len, int m, int n, char[][] board) {
        for (int i = 0 ; i < m ; i ++) {
            for (int j = 0 ; j < n ; j ++) {
                boolean[][] check = new boolean[m][n];
                check[i][j] = true;
                dfs(i, j, 1, len, board[i][j] + "", board, check);
            }
        }
    }

    private void dfs(int x, int y, int idx, int len, String word, char[][] board, boolean[][] check) {
        if (idx == len) {
            trie.insert(word);
            return;
        }

        for (int i = 0 ; i < 4 ; i ++) {
            int newX = x + row[i];
            int newY = y + col[i];
            if (newX < 0 || newX >= board.length || newY < 0 || newY >= board[0].length) continue;
            if (check[newX][newY]) continue;

            check[newX][newY] = true;
            dfs(newX, newY, idx + 1, len, word + board[newX][newY], board, check);
            check[newX][newY] = false;
        }
    }
}

class Trie {

    private Node root;

    public Trie() {
        this.root = new Node();
    }
    
    public void insert(String word) {
        Node current = this.root;

        for (char c : word.toCharArray()) {
            int idx = c - 'a';
            if (current.children[idx] == null) {
                current.children[idx] = new Node();
            }
            current = current.children[idx];
        }
        current.isEndOfWord = true;
    }

    public boolean search(String word) {
        Node current = this.root;

        for (char c : word.toCharArray()) {
            int idx = c - 'a';
            if (current.children[idx] == null) return false;

            current = current.children[idx];
        }

        return current.isEndOfWord;
    }
}

class Node {
    Node[] children;
    boolean isEndOfWord;

    Node() {
        this.children = new Node[26];
        this.isEndOfWord = false;
    }
}

결과

0개의 댓글

관련 채용 정보