Skip to content

Commit

Permalink
update 79 java
Browse files Browse the repository at this point in the history
  • Loading branch information
yennanliu committed Dec 27, 2024
1 parent 841ba30 commit e0aa3f5
Show file tree
Hide file tree
Showing 3 changed files with 162 additions and 30 deletions.
103 changes: 82 additions & 21 deletions leetcode_java/src/main/java/LeetCodeJava/BackTrack/WordSearch.java
Original file line number Diff line number Diff line change
Expand Up @@ -130,28 +130,89 @@ private boolean dfs_(char[][] board, int y, int x, int idx, String word, boolean
visited[y][x] = true;

int[][] dirs = {{0, 1}, {0, -1}, {1, 0}, {-1, 0}};
/**
* NOTE !!!
*
* instead of below structure:
*
* boolean didFindNextCharacter =
* dfs2(row + 1, col, word, lvl + 1, visited, board) ||
* dfs2(row - 1, col, word, lvl + 1, visited, board) ||
* dfs2(row, col + 1, word, lvl + 1, visited, board) ||
* dfs2(row, col - 1, word, lvl + 1, visited, board);
*
* we can use below logic as well:
*
* for (int[] dir : dirs) {
* if (dfs_(board, y + dir[0], x + dir[1], idx + 1, word, visited)) {
* return true;
* }
* }
*
*/
for (int[] dir : dirs) {
/**
* NOTE !!!
*
* instead of below structure:
*
* boolean didFindNextCharacter =
* dfs2(row + 1, col, word, lvl + 1, visited, board) ||
* dfs2(row - 1, col, word, lvl + 1, visited, board) ||
* dfs2(row, col + 1, word, lvl + 1, visited, board) ||
* dfs2(row, col - 1, word, lvl + 1, visited, board);
*
* we can use below logic as well:
*
* for (int[] dir : dirs) {
* if (dfs_(board, y + dir[0], x + dir[1], idx + 1, word, visited)) {
* return true;
* }
* }
*/
/**
* 1) Detailed Explanation:
*
* Role of return true in the Loop
*
* 1. Backtracking Recursion:
* • The function backtrack is called recursively to explore possible paths in the grid.
* • Each recursive call either returns true if the word can be constructed from the current path or false if it cannot.
*
* 2. Returning Early:
* • As soon as one of the recursive calls returns true (indicating the word has been found), there is no need to continue exploring other directions. The word has already been successfully constructed.
*
* 3. Efficiency:
* • Exiting the loop early saves computation by avoiding exploration of unnecessary paths.
*
*
* 2) What Happens Without return true?
*
* -> If the return true is omitted, the function will:
* 1. Continue to check all remaining directions in the directions array, even after finding a valid path.
* 2. Complete all recursive calls, backtrack, and ultimately return false for the current recursion level, even if a valid path exists deeper in the recursion tree.
*
* -> This would result in the algorithm failing to detect that the word is present in the grid.
*
*
* 3) Example:
* Let’s consider a small grid:
*
* board = [
* ['A', 'B'],
* ['C', 'D']
* ];
* word = "AB";
*
*
* Start at (0, 0) (value A), matching the first character.
* • Check neighbors:
* • Move right to (0, 1) (value B), matching the second character. At this point, the word is found, so we return true.
*
* With return true:
* • When the recursive call to (0, 1) returns true, the loop exits immediately, and the function propagates true all the way up.
*
* Without return true:
* • Even after (0, 1) finds the word, the function continues checking other directions (down, left, up), wasting computation. Eventually, it backtracks, losing the valid result.
*
*
*
*
*
* 4) Conclusion
*
* Returning true immediately when a valid path is found is
* both correct and efficient. It skips redundant exploration
* and ensures that the recursion terminates as soon as the word is found.
* Other recursive logic is unaffected since the backtracking process
* stops as soon as we achieve the goal.
*
*/
for (int[] dir : dirs) {
if (dfs_(board, y + dir[0], x + dir[1], idx + 1, word, visited)) {
/** NOTE !!!
*
* need to return true IMMEDIATELY if a true solution is found
*/
return true;
}
}
Expand Down
57 changes: 57 additions & 0 deletions leetcode_java/src/main/java/dev/workspace6.java
Original file line number Diff line number Diff line change
Expand Up @@ -599,5 +599,62 @@ public int[][] multiply(int[][] mat1, int[][] mat2) {
return res;
}

// LC 079
// https://leetcode.com/problems/word-search/
// 2.31 pm - 2.45 pm
public boolean exist(char[][] board, String word) {

if (board.length == 1 && board[0].length == 1){
return String.valueOf(board[0][0]).equals(word);
}

// backtrack
Set<List<Integer>> visited = new HashSet<>();
int l = board.length;
int w = board[0].length;
for(int i = 0; i < l; i++){
for(int j = 0; j < w; j++){
StringBuilder sb = new StringBuilder();
if(canFind(board, word, j, i, sb, visited)){
return true;
}
}
}

return false;
}

private boolean canFind(char[][] board, String word, int x, int y, StringBuilder cur, Set<List<Integer>> visited){
int l = board.length;
int w = board[0].length;
int[][] moves = new int[][]{ {0,1}, {0,-1}, {1,0}, {-1,0} };
if (cur.toString().length() == word.length() && cur.toString().equals(word)){
return true;
}
if (cur.toString().length() > word.length()){
return false; // ??
}

for (int[] move: moves){
int x_ = x + move[0];
int y_ = y + move[1];
List<Integer> tmp = new ArrayList<>();
tmp.add(x);
tmp.add(y);
String tmpVal = String.valueOf(board[y_][x_]);
if (x_ >= 0 && x_ < w && y_ >= 0 &&
y_ < l && !visited.contains(tmp) &&
tmpVal.equals(word.charAt(cur.length()+1))){
visited.add(tmp);
cur.append(board[y][x]); // ???
canFind(board, word, x_, y_, cur, visited);
// undo
cur.deleteCharAt(cur.toString().length() - 1);
visited.remove(tmp); // ??
}
}

return false;
}

}
32 changes: 23 additions & 9 deletions leetcode_java/src/main/java/dev/workspace7.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package dev;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class workspace7 {
public static void main(String[] args) {
Expand All @@ -16,15 +18,27 @@ public static void main(String[] args) {
// }

// ------------------- TEST 2
int[][] mat1 = new int[][]{ {1,0,0}, {-1,0,3} };
int[][] mat2 = new int[][]{ {7,0,0}, {0,0,0}, {0,0,1} };
int[][] res = multiply(mat1, mat2);
System.out.println(">>> res = ");
for (int i = 0; i < res.length; i++){
for (int j = 0; j < res[0].length; j++){
System.out.println(res[i][j]);
}
}
// int[][] mat1 = new int[][]{ {1,0,0}, {-1,0,3} };
// int[][] mat2 = new int[][]{ {7,0,0}, {0,0,0}, {0,0,1} };
// int[][] res = multiply(mat1, mat2);
// System.out.println(">>> res = ");
// for (int i = 0; i < res.length; i++){
// for (int j = 0; j < res[0].length; j++){
// System.out.println(res[i][j]);
// }
// }

// ------------------- TEST 3
// String a = "a";
// String b = "b";
// a += b;
// System.out.println(">> a = " + a);

// ------------------- TEST 4
List<String> x = new ArrayList<>();
x.add("a");
x.add("b");
System.out.println(x.toString());
}


Expand Down

0 comments on commit e0aa3f5

Please sign in to comment.