Word Search Board

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 cell itself does not count as an adjacent cell.
The same letter cell may be used more than once.

Example :

Given board =

[
  ["ABCE"],
  ["SFCS"],
  ["ADEE"]
]

word = "ABCCED", -> returns 1,
word = "SEE", -> returns 1,
word = "ABCB", -> returns 1,
word = "ABFSAB" -> returns 1
word = "ABCD" -> returns 0

Note that 1 corresponds to true, and 0 corresponds to false.

Solution:

BFS

public class Solution {
    static class Node {
        int x;
        int y;
        String str;
        
        public Node(int x, int y, String str) {
            this.x = x;
            this.y = y;
            this.str = str;
        }
        
        public boolean setString(String str, ArrayList<String> A) {
            int m = A.size();
            int n = A.get(0).length();
            if (x < 0 || x >= m || y < 0 || y >= n) {
                return false;
            }
            this.str = str + A.get(x).charAt(y);
            return true;
        }
        
        public boolean isValid(String target) {
            return target.startsWith(str);
        }
        
        @Override
        public int hashCode() {
            int hash = 31;
            hash += 17 * x;
            hash += 17 * y;
            hash += str.hashCode();
            return hash;
        } 
        
        @Override
        public boolean equals(Object o) {
            Node n = (Node) o;
            return x == n.x && y == n.y && str.equals(n.str);
        }
    }
    
    public int exist(ArrayList<String> A, String B) {
        Deque<Node> queue = new ArrayDeque<>();
        Set<Node> visited = new HashSet<>();
        int[] dx = new int[]{-1,0,1,0};
        int[] dy = new int[]{0,1,0,-1};
        char start = B.charAt(0);
        for (int i = 0; i < A.size(); i ++) {
            String s = A.get(i);
            for (int j = 0; j < s.length(); j ++) {
                if (s.charAt(j) == start) {
                    Node node = new Node(i, j, String.valueOf(start));
                    queue.offer(node);
                    visited.add(node);
                }
            }
        }
        while (!queue.isEmpty()) {
            Node node = queue.poll();
            if (node.str.equals(B)) {
                return 1;
            }
            for (int i = 0; i < 4; i ++) {
                Node next = new Node(node.x + dx[i], node.y + dy[i], "");
                if (next.setString(node.str, A) && next.isValid(B) && visited.add(next)) {
                    queue.offer(next);
                }
            }
        }
        return 0;
    }
}

dfs

class Solution {
    public boolean exist(char[][] board, String word) {
        int m = board.length;
        int n = board[0].length;
        for (int i = 0; i < m; i ++) {
            for (int j = 0; j < n; j ++) {
                char c = board[i][j];
                if (c == word.charAt(0)) {
                    boolean[][] visited = new boolean[m][n];
                    visited[i][j] = true;
                    if (dfs(board, i, j, word, 1, visited)) {
                        return true;
                    }
                }
            }
        }
        return false;
    }
    
    private boolean dfs(char[][] board, int x, int y, String word, int index, boolean[][] visited) {
        if (index == word.length()) return true; 
        int m = board.length;
        int n = board[0].length;
        visited[x][y] = true;
        int[] dx = new int[]{-1,0,1,0};
        int[] dy = new int[]{0,1,0,-1};
        for (int k = 0; k < 4; k ++) {
            int nx = x + dx[k];
            int ny = y + dy[k];
            int nVal = nx * n + ny;
            if (nx >= 0 && nx < m && ny >= 0 && ny < n && !visited[nx][ny] && board[nx][ny] == word.charAt(index)) {
                if (dfs(board, nx, ny, word, index + 1, visited)) {
                    return true;
                }
            }
        }
        visited[x][y] = false;
        return false;
    }
}