Jin's Library

ํ…œํ”Œ๋ฆฟ ์•Œ๊ณ ๋ฆฌ์ฆ˜ ๋ณธ๋ฌธ

Algorithm - Java

ํ…œํ”Œ๋ฆฟ ์•Œ๊ณ ๋ฆฌ์ฆ˜

Linkin 2025. 10. 21. 10:27

๐Ÿงฉ ํ…œํ”Œ๋ฆฟ์œผ๋กœ ์™ธ์›Œ๋‘๋ฉด ์ฝ”ํ…Œ·๋ฐฑ์ค€์—์„œ ๋ฌด์ ์ด ๋˜๋Š” ์•Œ๊ณ ๋ฆฌ์ฆ˜๋“ค

  1. DFS (์žฌ๊ท€ / ์Šคํƒ)
  2. BFS (ํ / ๊ฑฐ๋ฆฌ ๊ณ„์‚ฐ / ๋‹ค์ค‘ ์‹œ์ž‘)
  3. Union-Find (์„œ๋กœ์†Œ ์ง‘ํ•ฉ)
  4. Dijkstra (์šฐ์„ ์ˆœ์œ„ ํ ๊ธฐ๋ฐ˜ ์ตœ๋‹จ๊ฒฝ๋กœ)
  5. DP ํ…œํ”Œ๋ฆฟ ๋ชจ์Œ (1์ฐจ์›, ๋ฐฐ๋‚ญ, ๋ถ€๋ถ„ํ•ฉ ๋“ฑ)
  6. Topological Sort (์œ„์ƒ ์ •๋ ฌ)
  7. Kruskal / Prim (์ตœ์†Œ ์‹ ์žฅ ํŠธ๋ฆฌ)
  8. Binary Search (์ด๋ถ„ ํƒ์ƒ‰ + ์‘์šฉ: parametric search)
  9. Floyd-Warshall (๋ชจ๋“  ์Œ ์ตœ๋‹จ๊ฑฐ๋ฆฌ)
  10. Backtracking (์ˆœ์—ด / ์กฐํ•ฉ / ๋ถ€๋ถ„์ง‘ํ•ฉ)
  11. ์š”์•ฝ ์น˜ํŠธ์‹œํŠธ (ํ•ต์‹ฌ ํฌ์ธํŠธ / ๋ณต์Šต์šฉ)

1. DFS (Depth-First Search)

๋ชฉ์ : ๊ทธ๋ž˜ํ”„/๊ฒฉ์ž์—์„œ ๊นŠ๊ฒŒ ํƒ์ƒ‰(์—ฐ๊ฒฐ ์š”์†Œ, ๊ฒฝ๋กœ ์กด์žฌ, ๋ฐฑํŠธ๋ž˜ํ‚น ๋“ฑ)
ํ•ต์‹ฌ ์•„์ด๋””์–ด: ํ˜„์žฌ ๋…ธ๋“œ์—์„œ ๊ฐˆ ์ˆ˜ ์žˆ๋Š” ๊ณณ์„ ์žฌ๊ท€(๋˜๋Š” ์Šคํƒ)๋กœ ๋๊นŒ์ง€ ๋“ค์–ด๊ฐ€๊ณ , ๋” ์ด์ƒ ๊ฐˆ ๋ฐ ์—†์œผ๋ฉด ๋˜๋Œ์•„์˜ด.

์žฌ๊ท€ ํ…œํ”Œ๋ฆฟ (๊ทธ๋ž˜ํ”„: ์ธ์ ‘๋ฆฌ์ŠคํŠธ)

static boolean[] visited;
static ArrayList<Integer>[] graph;

static void dfs(int node) {
    visited[node] = true;
    // ์ž‘์—…: node ๋ฐฉ๋ฌธ ์‹œ ์ฒ˜๋ฆฌ (ex. count++, print ๋“ฑ)
    for (int nxt : graph[node]) {
        if (!visited[nxt]) dfs(nxt);
    }
}
  • ์‚ฌ์šฉ์ฒ˜: ์—ฐ๊ฒฐ ์š”์†Œ ๊ฐœ์ˆ˜, ๊ฒฝ๋กœ ์กด์žฌ ์—ฌ๋ถ€, ๋ฐฑํŠธ๋ž˜ํ‚น ๊ธฐ๋ฐ˜ ๋ฌธ์ œ
  • ์‹œ๊ฐ„: O(V + E), ๊ณต๊ฐ„: recursion depth (O(V)) + visited

2D ๊ฒฉ์ž DFS (๋ฏธ๋กœ, ์˜์—ญ ํƒ์ƒ‰)

static int[] dx = {-1,1,0,0};
static int[] dy = {0,0,-1,1};
static boolean[][] visited;
static int N, M;
static int[][] map; // ์กฐ๊ฑด์— ๋”ฐ๋ฅธ ๊ฐ’(1์ด๋ฉด ๋ฐฉ๋ฌธ ๊ฐ€๋Šฅ ๋“ฑ)

static void dfs(int x, int y) {
    visited[x][y] = true;
    // ์ž‘์—…: map[x][y] ์ฒ˜๋ฆฌ
    for (int d = 0; d < 4; d++) {
        int nx = x + dx[d], ny = y + dy[d];
        if (nx < 0 || ny < 0 || nx >= N || ny >= M) continue;
        if (!visited[nx][ny] && map[nx][ny] == 1) dfs(nx, ny);
    }
}

๋ฐ˜๋ณต(์Šคํƒ) ๋ฒ„์ „

Stack<int[]> st = new Stack<>();
st.push(new int[]{sx, sy});
visited[sx][sy] = true;
while (!st.isEmpty()) {
    int[] cur = st.pop();
    // ์ฒ˜๋ฆฌ
    for (...) {
        if (!visited[nx][ny] && condition) {
            visited[nx][ny] = true;
            st.push(new int[]{nx, ny});
        }
    }
}

์ฃผ์˜์  / ํŒ

  • ์žฌ๊ท€ ๊นŠ์ด ์ดˆ๊ณผ ์ฃผ์˜(์ž๋ฐ” ๊ธฐ๋ณธ ์•ฝ 10^4 ์ˆ˜์ค€). ๊นŠ์„ ๊ฒฝ์šฐ ์Šคํƒ ์‚ฌ์šฉํ•˜๊ฑฐ๋‚˜ -Xss ์˜ต์…˜, ํ˜น์€ ๋ฐ˜๋ณต๋ฌธ์œผ๋กœ ๋ณ€ํ™˜.
  • visited ํ‘œ์‹œ๋Š” ๋“ค์–ด๊ฐ€์ž๋งˆ์ž(์ง„์ž… ์งํ›„) ํ•ด์•ผ ๋ฌดํ•œ ๋ฃจํ”„ ๋ฐฉ์ง€.
  • ๊ทธ๋ž˜ํ”„๊ฐ€ ์—ฐ๊ฒฐ๋˜์ง€ ์•Š์•˜์œผ๋ฉด ๋ชจ๋“  ๋…ธ๋“œ์— ๋Œ€ํ•ด for ๋ฃจํ”„ ๋Œ๋ ค์•ผ ํ•จ.

2. BFS (Breadth-First Search)

๋ชฉ์ : ๊ฐ€๊นŒ์šด ๋…ธ๋“œ๋ถ€ํ„ฐ ๋ ˆ๋ฒจ๋ณ„ ํƒ์ƒ‰ — ๊ฐ€์ค‘์น˜๊ฐ€ ๊ฐ™์€ ๊ทธ๋ž˜ํ”„์—์„œ ์ตœ๋‹จ ๊ฑฐ๋ฆฌ ๋ณด์žฅ
ํ•ต์‹ฌ: ํ(FIFO)๋ฅผ ์‚ฌ์šฉํ•ด ๋ ˆ๋ฒจ๋ณ„ ํ™•์žฅ

๊ธฐ๋ณธ ํ…œํ”Œ๋ฆฟ (๊ทธ๋ž˜ํ”„)

Queue<Integer> q = new LinkedList<>();
boolean[] visited = new boolean[N+1];
q.add(start);
visited[start] = true;
while (!q.isEmpty()) {
    int cur = q.poll();
    // ์ฒ˜๋ฆฌ
    for (int nxt : graph[cur]) {
        if (!visited[nxt]) {
            visited[nxt] = true;
            q.add(nxt);
        }
    }
}

๊ฑฐ๋ฆฌ ๊ณ„์‚ฐ ํ…œํ”Œ๋ฆฟ (๊ฒฉ์ž ๋˜๋Š” ๊ทธ๋ž˜ํ”„)

int[] dist = new int[N+1];
Arrays.fill(dist, -1);
Queue<Integer> q = new LinkedList<>();
q.add(start);
dist[start] = 0;

while (!q.isEmpty()) {
    int cur = q.poll();
    for (int nxt : graph[cur]) {
        if (dist[nxt] == -1) {
            dist[nxt] = dist[cur] + 1;
            q.add(nxt);
        }
    }
}
// dist[target]์ด ์ตœ๋‹จ ๊ฑฐ๋ฆฌ(์—†์œผ๋ฉด -1)

๋‹ค์ค‘ ์‹œ์ž‘์  (ํ† ๋งˆํ† , ๋ถˆ ํ™•์‚ฐ ๋“ฑ)

  • ์ดˆ๊ธฐ ํ์— ์—ฌ๋Ÿฌ ์‹œ์ž‘์ ์„ ๋„ฃ๊ณ  dist[start]=0 ํ•˜์—ฌ ๋™์‹œ์— ํ™•์‚ฐ์‹œํ‚ด.

์ฃผ์˜์  / ํŒ

  • ๋ฐฉ๋ฌธ ์ฒดํฌ๋Š” ํ์— ๋„ฃ์„ ๋•Œ ํ•ด์•ผ ํ•จ(์ค‘๋ณต enqueue ๋ฐฉ์ง€).
  • ๋ฉ”๋ชจ๋ฆฌ: ํ์— ๋งŽ์€ ๋…ธ๋“œ๊ฐ€ ๋“ค์–ด์˜ฌ ์ˆ˜ ์žˆ์Œ(๊ฒฉ์ž ํฌ๊ธฐ ๋“ฑ ๊ณ ๋ ค).
  • BFS๋Š” ๊ฐ€์ค‘์น˜๊ฐ€ ๋™์ผํ•  ๋•Œ๋งŒ ์ตœ๋‹จ๊ฑฐ๋ฆฌ. ๊ฐ€์ค‘์น˜๊ฐ€ ๋‹ค๋ฅด๋ฉด Dijkstra ์‚ฌ์šฉ.

3. Union-Find (Disjoint Set)

๋ชฉ์ : ์ง‘ํ•ฉ ํ•ฉ์น˜๊ธฐ & ๊ฐ™์€ ์ง‘ํ•ฉ์ธ์ง€ ๋น ๋ฅด๊ฒŒ ํŒ์ • (์˜คํ”„๋ผ์ธ ์—ฐ๊ฒฐ์„ฑ, Kruskal ๋“ฑ)
ํ•ต์‹ฌ: ๋ฃจํŠธ(parent) ๋ฐฐ์—ด, ๊ฒฝ๋กœ ์••์ถ•, union by rank(optional)

ํ…œํ”Œ๋ฆฟ

static int[] parent;

static void makeSet(int n) {
    parent = new int[n+1];
    for (int i = 1; i <= n; i++) parent[i] = i;
}

static int find(int x) {
    if (parent[x] == x) return x;
    return parent[x] = find(parent[x]); // path compression
}

static void union(int a, int b) {
    a = find(a);
    b = find(b);
    if (a == b) return;
    parent[b] = a; // ํ˜น์€ rank ๊ธฐ๋ฐ˜์œผ๋กœ ํ•ฉ์น˜๊ธฐ
}

๋ณตํ•ฉ(๋žญํฌ ์‚ฌ์šฉ)

  • rank[] ๋˜๋Š” size[] ์‚ฌ์šฉํ•ด ์ž‘์€ ํŠธ๋ฆฌ๋ฅผ ํฐ ํŠธ๋ฆฌ์— ๋ถ™์ด๋ฉด ๊ท ํ˜• ์œ ์ง€.

์ฃผ์˜์ 

  • find์˜ ๋ฐ˜ํ™˜๊ฐ’์œผ๋กœ ๋น„๊ต(find(a)==find(b))ํ•ด์•ผ ํ•จ.
  • ์ดˆ๊ธฐํ™”(makeSet) ์žŠ์ง€ ์•Š๊ธฐ.

4. Dijkstra (์šฐ์„ ์ˆœ์œ„ ํ ๊ธฐ๋ฐ˜ ์ตœ๋‹จ๊ฒฝ๋กœ)

๋ชฉ์ : ๊ฐ€์ค‘์น˜(๋น„์Œ์ˆ˜) ๊ทธ๋ž˜ํ”„์˜ ๋‹จ์ผ ์ถœ๋ฐœ ์ตœ๋‹จ๊ฒฝ๋กœ
ํ•ต์‹ฌ: ์šฐ์„ ์ˆœ์œ„ ํ๋กœ ํ˜„์žฌ ์ตœ๋‹จ ํ›„๋ณด ์ •์  ์„ ํƒ, ์™„์ „์ตœ์ ํ™” ํƒ์ƒ‰

ํ…œํ”Œ๋ฆฟ

static final int INF = Integer.MAX_VALUE;
static ArrayList<int[]>[] graph; // graph[u] contains {v, cost}
static int[] dist;

static void dijkstra(int start) {
    PriorityQueue<int[]> pq = new PriorityQueue<>((a,b) -> a[1]-b[1]);
    dist = new int[n+1];
    Arrays.fill(dist, INF);
    dist[start] = 0;
    pq.add(new int[]{start, 0});

    while (!pq.isEmpty()) {
        int[] cur = pq.poll();
        int u = cur[0], d = cur[1];
        if (d > dist[u]) continue; // ์ด๋ฏธ ๋” ์งง์€ ๊ฒฝ๋กœ๊ฐ€ ์žˆ์Œ
        for (int[] edge : graph[u]) {
            int v = edge[0], w = edge[1];
            if (dist[v] > dist[u] + w) {
                dist[v] = dist[u] + w;
                pq.add(new int[]{v, dist[v]});
            }
        }
    }
}
  • ์‹œ๊ฐ„: O(E log V)

์ฃผ์˜์ 

  • ์Œ์ˆ˜ ๊ฐ€์ค‘์น˜ ์กด์žฌ ์‹œ Dijkstra ๋ถˆ๊ฐ€(๋ฒจ๋งŒ-ํฌ๋“œ ์‚ฌ์šฉ).
  • if (d > dist[u]) continue; ์ฒดํฌ ์ค‘์š”(์ค‘๋ณต PQ ์•„์ดํ…œ ๋ฌด์‹œ).

5. DP ํ…œํ”Œ๋ฆฟ ๋ชจ์Œ (๊ฐ„๋‹จ ํ•ต์‹ฌ ํŒจํ„ด)

1) 1์ฐจ์› ์ ํ™”์‹ (์—ฐ์†ํ•ฉ, ํ”ผ๋ณด๋‚˜์น˜๋ฅ˜)

dp[0] = base;
for (int i = 1; i <= N; i++) {
    dp[i] = f(dp[i-1], dp[i-2], ...); // ๋ฌธ์ œ์— ๋งž๊ฒŒ
}

2) 0/1 Knapsack (์—ญ๋ฐฉํ–ฅ 1์ฐจ์› ์••์ถ•)

int[] dp = new int[W+1];
for (int i = 0; i < N; i++) {
    for (int w = W; w >= weight[i]; w--) {
        dp[w] = Math.max(dp[w], dp[w-weight[i]] + value[i]);
    }
}

3) Unbounded Knapsack (๋ฌด์ œํ•œ)

for (int i = 0; i < N; i++) {
    for (int w = weight[i]; w <= W; w++) {
        dp[w] = Math.max(dp[w], dp[w-weight[i]] + value[i]);
    }
}

4) Subset Sum / Coin Change (๋ฐฉ๋ฒ• ์ˆ˜)

dp[0] = 1;
for (int coin : coins) {
    for (int j = coin; j <= target; j++) {
        dp[j] += dp[j-coin];
    }
}

5) ๋ฉ”๋ชจ์ด์ œ์ด์…˜(ํƒ‘๋‹ค์šด)

int[] memo = new int[MAX];
Arrays.fill(memo, -1);
int dfs(int state) {
    if (memo[state] != -1) return memo[state];
    memo[state] = compute(...);
    return memo[state];
}

์ฃผ์˜์ 

  • 1์ฐจ์› ์••์ถ•ํ•  ๋•Œ ์ „์ด ๋ฐฉํ–ฅ(์—ญ์ˆœ/์ •๋ฐฉํ–ฅ)์„ ๊ผผ๊ผผํžˆ ๋”ฐ์งˆ ๊ฒƒ.
  • ์ดˆ๊ธฐ๊ฐ’, ๋ถˆ๊ฐ€๋Šฅ ๊ฐ’ ์ฒ˜๋ฆฌ(-INF, INF, false ๋“ฑ) ์žŠ์ง€ ๋ง๊ธฐ.

6. Topological Sort (์œ„์ƒ ์ •๋ ฌ)

๋ชฉ์ : DAG์—์„œ ์ˆœ์„œ(์„ ํ–‰ ์กฐ๊ฑด)๋ฅผ ์ •ํ•˜๋Š” ์•Œ๊ณ ๋ฆฌ์ฆ˜
ํ…œํ”Œ๋ฆฟ

int[] indeg = new int[N+1];
Queue<Integer> q = new LinkedList<>();
for (int i = 1; i <= N; i++) if (indeg[i] == 0) q.add(i);

while (!q.isEmpty()) {
    int cur = q.poll();
    order.add(cur);
    for (int nxt : graph[cur]) {
        indeg[nxt]--;
        if (indeg[nxt] == 0) q.add(nxt);
    }
}
  • ์‚ฌ์šฉ ์˜ˆ: ์ž‘์—… ์Šค์ผ€์ค„, ์œ„์ƒ ์ •๋ ฌ์„ ํ†ตํ•œ DP(์ตœ์žฅ ๊ฒฝ๋กœ in DAG)

7. Kruskal / Prim (MST)

Kruskal (๊ฐ„๋‹จ)

Collections.sort(edges, (a,b) -> a[2] - b[2]);
makeSet(n);
int total = 0;
for (int[] e : edges) {
    if (find(e[0]) != find(e[1])) {
        union(e[0], e[1]);
        total += e[2];
    }
}

Prim (์šฐ์„ ์ˆœ์œ„ ํ ๊ธฐ๋ฐ˜)

PriorityQueue<int[]> pq = new PriorityQueue<>((a,b)->a[1]-b[1]);
boolean[] used = new boolean[n+1];
pq.add(new int[]{start, 0});
int total = 0;
while (!pq.isEmpty()) {
    int[] cur = pq.poll();
    if (used[cur[0]]) continue;
    used[cur[0]] = true; total += cur[1];
    for (int[] nxt : graph[cur[0]]) {
        if (!used[nxt[0]]) pq.add(new int[]{nxt[0], nxt[1]});
    }
}

8. Binary Search (์ด๋ถ„ ํƒ์ƒ‰)

ํ…œํ”Œ๋ฆฟ(์ •์ˆ˜ ๋ฐฐ์—ด์—์„œ ์ฐพ๊ธฐ)

int l = 0, r = n-1;
while (l <= r) {
    int mid = (l + r) >>> 1;
    if (arr[mid] == target) return mid;
    if (arr[mid] < target) l = mid + 1;
    else r = mid - 1;
}
return -1;

์‘์šฉ: Parametric Search(๊ฐ€๋Šฅ/๋ถˆ๊ฐ€๋Šฅ ํŒ์ •)

  • while (l <= r)๋กœ mid ์žก๊ณ , check(mid) ํ•จ์ˆ˜๋กœ ์กฐ๊ฑด ์ถฉ์กฑ ์—ฌ๋ถ€ ํŒ๋‹จ. (ex: ๋‚˜๋ฌด ์ž๋ฅด๊ธฐ, ๊ณต์œ ๊ธฐ ์„ค์น˜)

9. Floyd-Warshall (๋ชจ๋“  ์Œ ์ตœ๋‹จ๊ฑฐ๋ฆฌ)

for (int i = 1; i <= n; i++) for (int j = 1; j <= n; j++) dist[i][j] = (i==j?0:INF);
for edges: dist[u][v]=w;
for (int k = 1; k <= n; k++)
    for (int i = 1; i <= n; i++)
        for (int j = 1; j <= n; j++)
            dist[i][j] = Math.min(dist[i][j], dist[i][k] + dist[k][j]);
  • ์‹œ๊ฐ„: O(n^3) → n ≤ ~400 ์ •๋„๊นŒ์ง€ ์‹ค์šฉ์ 

10. Backtracking (์ˆœ์—ด/์กฐํ•ฉ/๋ถ€๋ถ„์ง‘ํ•ฉ)

์ˆœ์—ด

void perm(int idx) {
    if (idx == m) { print(); return; }
    for (int i = 0; i < n; i++) {
        if (used[i]) continue;
        used[i] = true;
        sel[idx] = arr[i];
        perm(idx+1);
        used[i] = false;
    }
}

์กฐํ•ฉ

void comb(int start, int depth) {
    if (depth == k) { print(); return; }
    for (int i = start; i < n; i++) {
        sel[depth] = arr[i];
        comb(i+1, depth+1);
    }
}

๊ฐ€์ง€์น˜๊ธฐ(Pruning)

  • ์ •๋ ฌ + ํ˜„์žฌ ํ•ฉ + ๋‚จ์€ ์ตœ๋Œ€ ํ•ฉ ๋น„๊ต → ๋ถˆํ•„์š” ๊ฐ€์ง€์น˜๊ธฐ ๊ฐ€๋Šฅ

11. ์š”์•ฝ ์น˜ํŠธ์‹œํŠธ (์™ธ์šฐ๊ธฐ์šฉ)

  • DFS: ์žฌ๊ท€, visited ๋จผ์ €, ์žฌ๊ท€ ๊นŠ์ด ์ฃผ์˜
  • BFS: ํ, enqueue ์‹œ visited=true, ๊ฑฐ๋ฆฌ dist[cur]+1
  • Union-Find: find()์— ๊ฒฝ๋กœ ์••์ถ•, union()์œผ๋กœ ํ•ฉ์น˜๊ธฐ
  • Dijkstra: PQ, if (d > dist[u]) continue;
  • 0/1 Knapsack: ์—ญ๋ฐฉํ–ฅ for (w = W..wt)
  • Unbounded Knapsack / Coin change: ์ •๋ฐฉํ–ฅ for (w = wt..W)
  • Toposort: indegree 0 → ํ
  • Kruskal: ๊ฐ„์„  ์ •๋ ฌ + union-find
  • Binary Search: ๋ฒ”์œ„๋ฅผ ์ค„์ด๋Š” check(mid) ํŒจํ„ด
  • Floyd: 3์ค‘ for (k,i,j)
  • Backtracking: ์žฌ๊ท€ + visited + ๋ณต๊ตฌ(restore)

๋งˆ์ง€๋ง‰์œผ๋กœ — ์•”๊ธฐ & ์—ฐ์Šต ํŒ

  1. ํ…œํ”Œ๋ฆฟ์€ ์งง๊ณ  ์ž์ฃผ ๋ณต์Šตํ•˜์„ธ์š”. ๋ฌธ์ œ ํ’€ ๋•Œ ๋ฐ”๋กœ ๋ถ™์—ฌ๋„ฃ์„ ์ˆ˜ ์žˆ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.
  2. ์ž‘์€ ์˜ˆ์‹œ๋กœ ์ˆ˜๋™ ์‹œ๋ฎฌ๋ ˆ์ด์…˜ ํ•ด๋ณด์„ธ์š” — ์ฝ”๋“œ๊ฐ€ ์™œ ๋™์ž‘ํ•˜๋Š”์ง€ ๋ณด์ด๋ฉด ๊ธฐ์–ต์ด ์˜ค๋ž˜๊ฐ‘๋‹ˆ๋‹ค.
  3. ํ•œ ๋ฒˆ์— ํ•œ ํŒจํ„ด์”ฉ ์ง‘์ค‘ ์—ฐ์Šต: ์˜ˆ) ํ•˜๋ฃจ๋Š” BFS ๋ฌธ์ œ 5๊ฐœ, ๋‹ค์Œ ๋‚  Union-Find 5๊ฐœ.
  4. ์ฝ”ํ…Œ ์ „์—๋Š” Scanner ๋Œ€์‹  BufferedReader, StringTokenizer ์‚ฌ์šฉ ํ…œํ”Œ๋ฆฟ์„ ์ค€๋น„ํ•˜์„ธ์š”.
  5. ์‹ค์ „์—์„œ๋Š” ์˜ค๋ฅ˜๋ฅผ ์ค„์ด๋ ค๋ฉด ์ฃผ์„ + ๋ณ€์ˆ˜๋ช…์„ ๋ช…ํ™•ํžˆ ํ•ด๋‘๋ฉด ์ข‹์Šต๋‹ˆ๋‹ค.

'Algorithm - Java' ์นดํ…Œ๊ณ ๋ฆฌ์˜ ๋‹ค๋ฅธ ๊ธ€

DFS, BFS Template  (0) 2025.10.21
๋ฐฑ์ค€์—์„œ ํ”„๋กœ๊ทธ๋ž˜๋จธ์Šค ์–‘์‹์ฒ˜๋Ÿผ  (0) 2022.06.08