
https://leetcode.com/problems/unique-paths/description/
m x n grid์ ๋ก๋ด์ด ์๋ค. ๋ก๋ด์ ์ฒ์์ grid[0][0]์ ์์นํด ์๋ค. ๋ก๋ด์ grid[m-1][n-1]๋ก ์ด๋ํ๋ ค๊ณ ํ๋ค. ๋ก๋ด์ ํ๋ฒ ์์ง์ผ ๋ ์๋ ๋๋ ์ค๋ฅธ์ชฝ์ผ๋ก ๋ฐ์ ์ด๋ํ์ง ๋ชปํ๋ค.
์ด๋ intํ m, n์ด ์ฃผ์ด์ก์ ๋, ๋ก๋ด์ด grid[m-1][n-1]๋ก ๋์ฐฉํ ์ ์๋ ๊ฐ๋ฅํ unique paths์ ์๋ฅผ ๋ฆฌํดํ๋ผ.
(๋จ, ๋ต์ 2 * 10^9 ์ดํ์ ์๊ฐ๋ณต์ก๋๋ฅผ ๊ฐ์ ธ์ผ ํ๋ค.)
๐ง์ ์ฝ ์กฐ๊ฑด
1 <= m, n <= 10^2
=> ๋ง์ฝ ์์ ํ์ํ ๊ฒฝ์ฐ, O(N^2) = 10^4์ด๋ฏ๋ก ๊ฐ๋ฅ!
But recursive function์ผ๋ก ๊ตฌํํ ๊ฒฝ์ฐ -> O(2^N) = 2^100์ ๋ถ๊ฐ!

์ฒ์์๋ ๋ฐ๋ก mississippi์ ๊ฐ์ด ์์ด์ด ๋ ์ฌ๋ผ์ ์ค๋ณต๋ ์์๋ฅผ ๋๋๋ ๊ฒ์ผ๋ก ์ ๊ทผํ๋ค. ์ฆ, ์์ ๊ฐ์ ํ
์คํธ ์ผ์ด์ค๊ฐ ์์ ๋, ๊ฐ ๋์จ๋ค.
์ด๊ฒ์ ์ผ๋ฐํ์ํค๋ฉด, ๋ก ๋ํ๋ผ ์ ์๋ค.
public class UniquePathSolution {
public int uniquePaths(int m, int n) {
HashMap<Integer, Integer> memo = new HashMap<>();
return fact(n + m - 2, memo) / (fact(n - 1, memo) * fact(m - 1, memo));
}
private static int fact(int x, HashMap<Integer, Integer> memo) {
// base condition
if (x <= 1) {
return 1;
}
if (!memo.containsKey(x)) {
memo.put(x, fact(x - 1, memo) * x);
}
return memo.get(x);
}
}
๐ค๋ฐ๋ผ์ ์กฐํฉ๋ก ์ผ๋ก ์ ๊ทผํ๋ ๋์ , ์ง์ ๊ทธ๋ฆผ์ ๊ทธ๋ ค๊ฐ๋ฉด์ ์ ์ ํ ์๊ณ ๋ฆฌ์ฆ์ ์ฐพ๋ ์ ๋ฐ์ ์๋ค.
memo.put(new Point(0, 0))๊ณผ ๊ฐ์ด ์ปค์คํ
ํด๋์ค๋ฅผ HashMap์ ํค(key)๋ก ์ฌ์ฉํ ๋, dp์์ ์ฌ๊ท์ ์ผ๋ก ํธ์ถํ๋ค๊ฐ ๋์ผํ ์๋ฏธ์ ์ขํ๊ฐ ์ ๋ฌ๋๋๋ผ๋ new Point(0, 0)์ฒ๋ผ ์ ์ธ์คํด์ค๋ฅผ ๋ง๋ค๋ฉด ์๋ก ๋ค๋ฅธ ๊ฐ์ฒด๋ก ๊ฐ์ฃผ๋๋ค.
์ด๋ฅผ ํด๊ฒฐํ๊ธฐ ์ํด ๋ฒ๊ฑฐ๋กญ๊ฒ hashCode()์ equals()๋ฅผ ์ค๋ฒ๋ผ์ด๋ฉ ํด์ผ ํ๋๋ฐ ์ฝ๋๊ฐ ๋งค์ฐ ์ง์ ๋ถํ๋ฏ๋ก,
๐จ๋ฐฐ์ด ํ์
์ dp๋ฅผ ์ฌ์ฉํ์.
์ ๋ง ๊ฐ๋จํ๊ฒ ๋
ธํธ์ grid ๊ทธ๋ฆผ ๊ทธ๋ฆฌ๊ณ ์ค๊ณ ๋ฉ ์์ ๋ ํ๋ ๋ฐฉ๋ฒ์ผ๋ก unique paths๋ฅผ ๋ค์๊ณผ ๊ฐ์ด ๊ตฌํด๋ณด์๋ค.

1. ๊ฐ ๋ชจ์๋ฆฌ๋ก ๊ฐ๋ ๋ฐฉ๋ฒ์ 1๊ฐ์ง ๋ฐ์ ์๊ธฐ ๋๋ฌธ์ ๋ชจ์๋ฆฌ๋ฅผ ๋ชจ๋ 1๋ก ์ฑ์ด๋ค.
2. ๊ฐ ์
๋ค์ ๋ฐฉ๋ฒ ์๋ฅผ ๋ํ ๋ค์, ์ข
์ ์ ๋๋ฌํ ๋๊น์ง ๋ํ๋ ๊ณผ์ ์ ๋ฐ๋ณตํ๋ค.
...์ฑ์ด๋ค, ์ฑ์ด๋ค, ๋ฐ๋ก tabulation ๊ธฐ๋ฒ์ด ๋ ์ค๋ฅด์ง ์์๊ฐ!?? ๊ทธ๋ ๋ค. ์ด ๋ฌธ์ ๋ ์์ฐ์ค๋ฝ๊ฒ Bottom-up์ผ๋ก ํ ์๊ฐ ์๋ ๊ฒ์ด๋ค.
๐ค์๋ grid๋ ์์์ ๊ทธ๋ํ๋ก ํํํ ์ ์์ผ๋๊น bfs๋ dfs๋ก๋ ํ ์ ์๋๊ฑฐ ์๋๊ฐ์?
๐ใดใด. ์ด์ ์ ํ์๋ The shortest path in a binary matrix์์๋ ์์ ์์ (dr, dc ์ธํ
ํด์)bfs๋ก ๊ฐ์ฅ ์งง์ ๊ฒฝ๋ก๋ฅผ ๊ตฌํ์ง๋ง, ์ด ๋ฌธ์ ๋ ๊ฒฝ๋ก(๋ฐฉ๋ฒ)์ ๊ฐ์๋ฅผ ๊ตฌํ๋ ๊ฒ์ด ๋ชฉ์ ์ด๋ฏ๋ก dp๊ฐ ๊ฐ์ฅ ์ ์ ํ๋ค.
๐ฏ๋ฌธ์ ์์ dp๋ก ํ๋ผ๋ ํํธ๋ค ์ฐธ๊ณ ํ ๊ฒ!
๋ฐ๋ผ์ tabulation ๊ธฐ๋ฒ์ ํ์ฉํด์ ๋ค์๊ณผ ๊ฐ์ด ์ฝ๋๋ฅผ ๊ตฌํํ ์ ์๋ค.
public class UniquePathSolution {
public int uniquePaths(int m, int n) {
// m x n ํฌ๊ธฐ์ dp๋ฅผ ์ด๊ธฐํ
int[][] dp = new int[m][n];
// ๋ชจ์๋ฆฌ๋ฅผ 1๋ก ๋ชจ๋ ์ฑ์ด๋ค.
for (int i = 0; i < m; i++) {
dp[i][0] = 1;
}
for (int j = 0; j < n; j++) {
dp[0][j] = 1;
}
// ๋ชจ์๋ฆฌ์ ํฉ์ผ๋ก ์ข
์ ์ ๊ฐ์ ๋ฆฌํด
for (int i = 1; i < m; i++) {
for (int j = 1; j < n; j++) {
dp[i][j] = dp[i - 1][j] + dp[i][j - 1];
}
}
return dp[m - 1][n - 1];
}
}
dp[i][j] = dp[i - 1][j] + dp[i][j - 1]๋ก ๊ณ์ํด์ grid์ ๊ฐ์ ์ฑ์๋๊ฐ๋ค.๐ฎ๊ทธ๋ฐ๋ฐ, LeetCode์ ํ ์ฒ์ฌ์ ์ธ ์ฌ์ฉ์๊ฐ ์๋ ๊ทธ๋ฆผ๊ณผ ๊ฐ์ด grid๋ฅผ ์๊ณ ๋ฐฉํฅ์ผ๋ก 45๋ ๋๋ฆฌ๋ฉด ์ ํํ ํ์ค์นผ์ ์ผ๊ฐํ์ด ๋์จ๋ค๊ณ ํ์๋ค!!

๊ทธ๋ ๋ค. ๊ฒฝ๋ก๋ฅผ ๊ฐฑ์ ํ๊ธฐ ์ํ ์ ์์์ ์ฌ์ค์ ํ์ค์นผ์ ์ผ๊ฐํ ๋ฒ์น์ธ ์์ ๋์จ ๊ฒ์ด์๋ค.
๋ชจ๋ grid๋ฅผ ์ํํด์ ๊ฐ์ผ๋ก ์ฑ์ฐ๊ธฐ ๋๋ฌธ์ ์ด ๊ฑธ๋ฆฐ๋ค.
if r == 0 and c == 0:
memo[r][c] = 1
return memo[r][c]
int uniquePath = 0์ผ๋ก ์ค์ public class UniquePathSolution {
public int uniquePaths(int m, int n) {
int[][] memo = new int[m][n];
// ํ์ -1๋ก ์ฑ์ด๋ค
for (int i = 0; i < m; i++) {
Arrays.fill(memo[i], -1);
}
return dp(m - 1, n - 1, memo);
}
private static int dp(int r, int c, int[][] memo) {
// base condition
if (r == 0 && c == 0) {
memo[r][c] = 1;
return memo[r][c];
}
int uniquePath = 0;
// dp ํธ์ถ ์กฐ๊ฑด
if (memo[r][c] == -1) {
if (r > 0) {
uniquePath += dp(r - 1, c, memo);
}
if (c > 0) {
uniquePath += dp(r, c - 1, memo);
}
memo[r][c] = uniquePath; // ๋ฉ๋ชจ์ด์ ์ด์
์ด์ฉ
}
return memo[r][c];
}
}
int uniquePath = 0๋ก ์ค์ ํ ์ด์ ๋, ์์์ ์ค๋ ๊ฐ๊ณผ ์ผ์ชฝ์์ ์ค๋ ๊ฐ์ ์ด๊ธฐ ์ํ๋ก๋ถํฐ ๊ฐ๊ฐ ๊ณ์ฐํ๊ธฐ ์ํด์๋ค.caller ํจ์์ uniquePath์ callee ํจ์์ uniquePath๋ ๊ฐ๊ฐ ๋ค๋ฅธ ์คํ ํ๋ ์์ ์กด์ฌํ๋ฏ๋ก, ์๋ก ๋
๋ฆฝ์ ์ธ ๊ฐ์ ๊ฐ์ง๊ฒ ๋๊ธฐ ๋๋ฌธ์ callee์์ ๊ณ์ฐํ ๊ฐ์ ๋ฆฌํดํด์ caller ํจ์๋ก ๋์ ํด์ ๊ฐ์ ๊ตฌํ ์๊ฐ ์๋ ๊ฒ์ด๋ค.๐๋ฌธ์ ์กฐ๊ฑด์์ "๋ก๋ด์ ํ๋ฒ ์์ง์ผ ๋ ์๋ ๋๋ ์ค๋ฅธ์ชฝ์ผ๋ก ๋ฐ์ ์ด๋ํ์ง ๋ชปํ๋ค."๋ผ๋ ๊ฒ์ Bottom-up์์๋ ์ ํ์์์ ๋ํ๊ธฐ ์ฐ์ฐ์๋ก, Top-down์์๋ if๋ฌธ ๋ฐ dp ํธ์ถ์ ๋ฐ๋ก๋ฐ๋ก ํด์ผ ํ๋ค๋ ๊ฒ์ ์ ์ ์๋ค.
grid๊ฐ ๋ณด์ธ๋ค๊ณ ๋ฌด์ง์ฑ์ผ๋ก bfs ๋๋ dfs๋ฅผ ์ธ ๊ฒ์ด ์๋๋ผ, ๋ฐ๋์ ์๋ฃ๊ตฌ์กฐ ๋ฐ ์๊ณ ๋ฆฌ์ฆ์ ์ ํํ๊ธฐ ์ ์ naiveํ๊ฒ ๋ฌธ์ ๋ฅผ ๋จผ์ ํ์ด๋ณด๊ณ ์ ํํ ๊ฒ!