From b237a1a6c36212897c072e7542f440f7a9092617 Mon Sep 17 00:00:00 2001 From: Peter Chen Date: Mon, 8 Sep 2025 10:44:57 +0800 Subject: [PATCH 1/2] Add unit tests for the "Word Search" problem. --- src/WordSearch79.java | 50 ------------------ .../com/leetcode/medium/WordSearch79.java | 39 ++++++++++++++ .../com/leetcode/medium/WordSearch79Test.java | 51 +++++++++++++++++++ 3 files changed, 90 insertions(+), 50 deletions(-) delete mode 100644 src/WordSearch79.java create mode 100644 src/main/java/com/leetcode/medium/WordSearch79.java create mode 100644 src/test/java/com/leetcode/medium/WordSearch79Test.java diff --git a/src/WordSearch79.java b/src/WordSearch79.java deleted file mode 100644 index d9d8914..0000000 --- a/src/WordSearch79.java +++ /dev/null @@ -1,50 +0,0 @@ -// Array ,Backtracking, Matrix - -import java.util.AbstractMap.SimpleEntry; -import java.util.Set; -import java.util.HashSet; - -public class WordSearch79 { - /* - w:length of word - Time Complexity : O(m*n*4^w) - Space Complexity : O(w) - */ - public boolean dfs(int r, int c, int index, String word, Set> visited, char[][] board) { - int rows = board.length; - int cols = board[0].length; - if (index == word.length()) { - return true; - } - if (r < 0 || r == rows || c < 0 || c == cols || visited.contains(new SimpleEntry<>(r, c)) || board[r][c] != word.charAt(index)) { - return false; - } - visited.add(new SimpleEntry<>(r, c)); - if (this.dfs(r + 1, c, index + 1, word, visited, board) || this.dfs(r - 1, c, index + 1, word, visited, board) || this.dfs(r, c + 1, index + 1, word, visited, board) || this.dfs(r, c - 1, index + 1, word, visited, board)) { - return true; - } - visited.remove(new SimpleEntry<>(r, c)); - return false; - } - - public boolean exist(char[][] board, String word) { - int rows = board.length; - int cols = board[0].length; - Set> visited = new HashSet<>(); - for (int r = 0; r < rows; r++) { - for (int c = 0; c < cols; c++) { - if (this.dfs(r, c, 0, word, visited, board)) { - return true; - } - } - } - return false; - } - - public static void main(String[] args) { - char[][] board = {{'A', 'B', 'C', 'E'}, {'S', 'F', 'C', 'S'}, {'A', 'D', 'E', 'E'}}; - String word = "ABCCED"; - System.out.println(new WordSearch79().exist(board, word)); - // true - } -} diff --git a/src/main/java/com/leetcode/medium/WordSearch79.java b/src/main/java/com/leetcode/medium/WordSearch79.java new file mode 100644 index 0000000..ed43c6a --- /dev/null +++ b/src/main/java/com/leetcode/medium/WordSearch79.java @@ -0,0 +1,39 @@ +// Tags: Backtracking, DFS +package com.leetcode.medium; + +import java.util.HashSet; +import java.util.Set; + +public class WordSearch79 { + private boolean dfs(int r, int c, char[][] board, String word, int index, Set visited) { + String key = r + ";" + c; + if (index == word.length()) { + return true; + } + if (r < 0 || r == board.length || c < 0 || c == board[0].length || visited.contains(key) || word.charAt(index) != board[r][c]) { + return false; + } + visited.add(key); + if (this.dfs(r + 1, c, board, word, index + 1, visited) || this.dfs(r - 1, c, board, word, index + 1, visited) || this.dfs(r, c + 1, board, word, index + 1, visited) || this.dfs(r, c - 1, board, word, index + 1, visited)) { + return true; + } + visited.remove(key); + return false; + } + /* + w: length of word + Time complexity: O(m*n*4^w) + Space complexity: O(w) + */ + public boolean exist(char[][] board, String word) { + Set visited = new HashSet<>(); + for (int r = 0; r < board.length; r++) { + for (int c = 0; c < board[0].length; c++) { + if (this.dfs(r, c, board, word, 0, visited)) { + return true; + } + } + } + return false; + } +} diff --git a/src/test/java/com/leetcode/medium/WordSearch79Test.java b/src/test/java/com/leetcode/medium/WordSearch79Test.java new file mode 100644 index 0000000..680dcef --- /dev/null +++ b/src/test/java/com/leetcode/medium/WordSearch79Test.java @@ -0,0 +1,51 @@ +package com.leetcode.medium; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import java.time.Duration; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTimeoutPreemptively; + +public class WordSearch79Test { + private WordSearch79 solution; + + @BeforeEach + void setUp() { + solution = new WordSearch79(); + } + + @Test + void testExist_Example1() { + char[][] board = {{'A', 'B', 'C', 'E'}, {'S', 'F', 'C', 'S'}, {'A', 'D', 'E', 'E'}}; + String word = "ABCCED"; + boolean expected = true; + + boolean result = assertTimeoutPreemptively(Duration.ofMillis(100), () -> solution.exist(board, word)); + + assertEquals(expected, result); + } + + @Test + void testExist_Example2() { + char[][] board = {{'A', 'B', 'C', 'E'}, {'S', 'F', 'C', 'S'}, {'A', 'D', 'E', 'E'}}; + String word = "SEE"; + boolean expected = true; + + boolean result = assertTimeoutPreemptively(Duration.ofMillis(100), () -> solution.exist(board, word)); + + assertEquals(expected, result); + } + + @Test + void testExist_Example3() { + char[][] board = {{'A', 'B', 'C', 'E'}, {'S', 'F', 'C', 'S'}, {'A', 'D', 'E', 'E'}}; + String word = "ABCB"; + boolean expected = false; + + boolean result = assertTimeoutPreemptively(Duration.ofMillis(100), () -> solution.exist(board, word)); + + assertEquals(expected, result); + } +} From 8b80f627cda3ff48d13594cf31cc96b2e8641023 Mon Sep 17 00:00:00 2001 From: Peter Chen Date: Mon, 8 Sep 2025 10:52:50 +0800 Subject: [PATCH 2/2] Optimize WordSearch79 visited tracking with boolean array. --- .../java/com/leetcode/medium/WordSearch79.java | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/src/main/java/com/leetcode/medium/WordSearch79.java b/src/main/java/com/leetcode/medium/WordSearch79.java index ed43c6a..8d1f9ad 100644 --- a/src/main/java/com/leetcode/medium/WordSearch79.java +++ b/src/main/java/com/leetcode/medium/WordSearch79.java @@ -1,23 +1,19 @@ // Tags: Backtracking, DFS package com.leetcode.medium; -import java.util.HashSet; -import java.util.Set; - public class WordSearch79 { - private boolean dfs(int r, int c, char[][] board, String word, int index, Set visited) { - String key = r + ";" + c; + private boolean dfs(int r, int c, char[][] board, String word, int index, boolean[][] visited) { if (index == word.length()) { return true; } - if (r < 0 || r == board.length || c < 0 || c == board[0].length || visited.contains(key) || word.charAt(index) != board[r][c]) { + if (r < 0 || r == board.length || c < 0 || c == board[0].length || visited[r][c] || word.charAt(index) != board[r][c]) { return false; } - visited.add(key); + visited[r][c] = true; if (this.dfs(r + 1, c, board, word, index + 1, visited) || this.dfs(r - 1, c, board, word, index + 1, visited) || this.dfs(r, c + 1, board, word, index + 1, visited) || this.dfs(r, c - 1, board, word, index + 1, visited)) { return true; } - visited.remove(key); + visited[r][c] = false; return false; } /* @@ -26,7 +22,9 @@ private boolean dfs(int r, int c, char[][] board, String word, int index, Set visited = new HashSet<>(); + int rows = board.length; + int cols = board[0].length; + boolean[][] visited = new boolean[rows][cols]; for (int r = 0; r < board.length; r++) { for (int c = 0; c < board[0].length; c++) { if (this.dfs(r, c, board, word, 0, visited)) {