This problem need to solve mutiple Strings, so we use a Trie to store all strings, and then do DFS.
Time complexity: O(m*n*3L), L is the maximum of the word.
Space complexity: O(K+L) = O(K), K is the number of all letters of words. L is the maximum of the word.
class Solution { int m, n; Set<String> res = new HashSet<>(); class Trie { String word = ""; Trie[] next = new Trie[26]; public void insert(String word) { char[] cs = word.toCharArray(); Trie cur = this; for (char c : cs) { if (cur.next[c - 'a'] == null) cur.next[c - 'a'] = new Trie(); cur = cur.next[c - 'a']; } cur.word = word; } } public List<String> findWords(char[][] board, String[] words) { m = board.length; n = board[0].length; Trie t = new Trie(); visited = new boolean[m][n]; for (String s : words) { t.insert(s); } for (int i = 0; i < m; i++) { for (int j = 0; j < n; j++) { dfs(board, t, i, j); } } return new ArrayList<String>(res); } private boolean[][] visited; private int[][] dirs = {{0, 1}, {0, -1}, {-1, 0}, {1, 0}}; private void dfs(char[][] board, Trie t, int x, int y) { t=t.next[board[x][y] - 'a']; if (t == null) return; if (t.word.length()>0) { res.add(t.word); } visited[x][y] = true; for (int[] dir : dirs) { int p = x + dir[0]; int q = y + dir[1]; if (valid(board, p, q) && !visited[p][q]) dfs(board, t, p, q); } visited[x][y] = false; } private boolean valid(char[][] board, int i, int j) { if (i < 0 || i >= m || j < 0 || j >= n) return false; return true; } }