diff --git a/src/UniquePaths62.java b/src/UniquePaths62.java deleted file mode 100644 index d6651e3..0000000 --- a/src/UniquePaths62.java +++ /dev/null @@ -1,36 +0,0 @@ -// Dynamic Programming, Math, Combinatorics - -import java.util.Map; -import java.util.HashMap; - -public class UniquePaths62 { - private int dfs(int m, int n, Map memo) { - String key = m + "," + n; - if (memo.containsKey(key)) { - return memo.get(key); - } - if (m == 0 || n == 0) { - return 0; - } - if (m == 1 || n == 1) { - return 1; - } - memo.put(key, this.dfs(m - 1, n, memo) + this.dfs(m, n - 1, memo)); - return memo.get(key); - } - - /* - Time complexity : O(m*n) - Space complexity : O(m+n) - */ - public int uniquePathsMemoization(int m, int n) { - Map memo = new HashMap<>(); - return this.dfs(m, n, memo); - } - - public static void main(String[] args) { - int m = 3; - int n = 7; - System.out.println(new UniquePaths62().uniquePathsMemoization(m, n)); // 28 - } -} diff --git a/src/main/java/com/leetcode/medium/UniquePaths62.java b/src/main/java/com/leetcode/medium/UniquePaths62.java new file mode 100644 index 0000000..dc50fbc --- /dev/null +++ b/src/main/java/com/leetcode/medium/UniquePaths62.java @@ -0,0 +1,45 @@ +// Tags: Dynamic Programming, DFS +package com.leetcode.medium; + +import java.util.HashMap; +import java.util.Map; + +public class UniquePaths62 { + private int uniquePathsMemoizationRecursive(int m, int n, Map memo) { + if (m == 1 || n == 1) { + return 1; + } + String key = m + "," + n; + if (memo.containsKey(key)) { + return memo.get(key); + } + memo.put(key, this.uniquePathsMemoizationRecursive(m - 1, n, memo) + this.uniquePathsMemoizationRecursive(m, n - 1, memo)); + return memo.get(key); + } + + /** + * Time complexity: O(m*n) + *

+ * Space complexity: O(m+n) + */ + public int uniquePathsMemoization(int m, int n) { + return this.uniquePathsMemoizationRecursive(m, n, new HashMap<>()); + } + + /** + * Time complexity: O(m*n) + *

+ * Space complexity: O(m*n) + */ + public int uniquePathsTabulation(int m, int n) { + int[][] dp = new int[m + 1][n + 1]; + dp[1][1] = 1; + for (int i = 0; i <= m; i++) { + for (int j = 0; j <= n; j++) { + if (i + 1 <= m) dp[i + 1][j] += dp[i][j]; + if (j + 1 <= n) dp[i][j + 1] += dp[i][j]; + } + } + return dp[m][n]; + } +} diff --git a/src/test/java/com/leetcode/medium/UniquePaths62Test.java b/src/test/java/com/leetcode/medium/UniquePaths62Test.java new file mode 100644 index 0000000..21694cf --- /dev/null +++ b/src/test/java/com/leetcode/medium/UniquePaths62Test.java @@ -0,0 +1,84 @@ +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 UniquePaths62Test { + private UniquePaths62 solution; + + @BeforeEach + void setUp() { + solution = new UniquePaths62(); + } + + @Test + void testUniquePathsMemoization_Example1() { + int m = 3; + int n = 7; + int expected = 28; + + int result = assertTimeoutPreemptively(Duration.ofMillis(100), () -> solution.uniquePathsMemoization(m, n)); + + assertEquals(expected, result); + } + + @Test + void testUniquePathsMemoization_Example2() { + int m = 3; + int n = 2; + int expected = 3; + + int result = assertTimeoutPreemptively(Duration.ofMillis(100), () -> solution.uniquePathsMemoization(m, n)); + + assertEquals(expected, result); + } + + @Test + void testUniquePathsMemoization_Example3() { + int m = 23; + int n = 12; + int expected = 193536720; + + int result = assertTimeoutPreemptively(Duration.ofMillis(100), () -> solution.uniquePathsMemoization(m, n)); + + assertEquals(expected, result); + } + + @Test + void testUniquePathsTabulation_Example1() { + int m = 3; + int n = 7; + int expected = 28; + + int result = assertTimeoutPreemptively(Duration.ofMillis(100), () -> solution.uniquePathsTabulation(m, n)); + + assertEquals(expected, result); + } + + @Test + void testUniquePathsTabulation_Example2() { + int m = 3; + int n = 2; + int expected = 3; + + int result = assertTimeoutPreemptively(Duration.ofMillis(100), () -> solution.uniquePathsTabulation(m, n)); + + assertEquals(expected, result); + } + + @Test + void testUniquePathsTabulation_Example3() { + int m = 23; + int n = 12; + int expected = 193536720; + + int result = assertTimeoutPreemptively(Duration.ofMillis(100), () -> solution.uniquePathsTabulation(m, n)); + + assertEquals(expected, result); + } +}