๐ŸŒ€ ์ดˆ๋ณด์ž์šฉ ๊ฐ€์ด๋“œ โ€˜Minimum Cost Path with Teleportationsโ€™ - LeetCode 3651 (C++, Python, JavaScript)

๋ฐœํ–‰: (2026๋…„ 1์›” 28์ผ ์˜ค์ „ 10:08 GMT+9)
8 ๋ถ„ ์†Œ์š”
์›๋ฌธ: Dev.to

Source: Dev.to

๋ฒˆ์—ญ์„ ์ง„ํ–‰ํ•˜๋ ค๋ฉด ๋ฒˆ์—ญํ•˜๊ณ ์ž ํ•˜๋Š” ๋ณธ๋ฌธ ํ…์ŠคํŠธ๋ฅผ ์ œ๊ณตํ•ด ์ฃผ์‹œ๊ฒ ์–ด์š”? ํ˜„์žฌ ์ œ๊ณต๋œ ๋‚ด์šฉ์€ ์†Œ์Šค ๋งํฌ๋ฟ์ด๋ผ ๋ฒˆ์—ญํ•  ํ…์ŠคํŠธ๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค. ํ…์ŠคํŠธ๋ฅผ ์•Œ๋ ค์ฃผ์‹œ๋ฉด ํ•œ๊ตญ์–ด๋กœ ๋ฒˆ์—ญํ•ด ๋“œ๋ฆฌ๊ฒ ์Šต๋‹ˆ๋‹ค.

Problem Overview

๊ทธ๋ฆฌ๋“œ๋ฅผ ํƒ์ƒ‰ํ•˜๋Š” ๊ฒƒ์€ ๊ณ ์ „์ ์ธ ์ฝ”๋”ฉ ๋ฌธ์ œ์ด์ง€๋งŒ, ํ…”๋ ˆํฌํ…Œ์ด์…˜์„ ์ถ”๊ฐ€ํ•˜๋ฉด ๊ฒŒ์ž„์ด ์™„์ „ํžˆ ๋ฐ”๋€๋‹ˆ๋‹ค.
๋‹ค์Œ์ด ์ฃผ์–ด์ง‘๋‹ˆ๋‹ค:

  • ๊ฐ ์…€์— ๋น„์šฉ์ด ๋“ค์–ด ์žˆ๋Š” m x n ํฌ๊ธฐ์˜ 2์ฐจ์› ๊ทธ๋ฆฌ๋“œ.
  • ํ…”๋ ˆํฌํŠธํ•  ์ˆ˜ ์žˆ๋Š” ์ตœ๋Œ€ ํšŸ์ˆ˜๋ฅผ ๋‚˜ํƒ€๋‚ด๋Š” ์ •์ˆ˜ k.
  • ๋‘ ๊ฐ€์ง€ ์ด๋™ ๊ทœ์น™:
    1. ํ‘œ์ค€ ์ด๋™ โ€“ ์˜ค๋ฅธ์ชฝ ๋˜๋Š” ์•„๋ž˜์ชฝ์œผ๋กœ ์ด๋™ํ•˜๋ฉฐ, ๋ชฉ์ ์ง€ ์…€์˜ ๊ฐ’๋งŒํผ ๋น„์šฉ์ด ๋“ญ๋‹ˆ๋‹ค.
    2. ํ…”๋ ˆํฌํ…Œ์ด์…˜ โ€“ ํ˜„์žฌ ์…€์˜ ๊ฐ’๋ณด๋‹ค **โ‰ค**์ธ ๋ชจ๋“  ์…€๋กœ ์ ํ”„ํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ, ๋น„์šฉ์€ 0์ž…๋‹ˆ๋‹ค.

Goal: ์™ผ์ชฝ ์œ„ ์…€ (0,0)์—์„œ ์˜ค๋ฅธ์ชฝ ์•„๋ž˜ ์…€ (mโ€‘1,nโ€‘1)๊นŒ์ง€ ์ด๋™ํ•˜๋Š” ์ตœ์†Œ ์ด ๋น„์šฉ์„ ๊ณ„์‚ฐํ•˜์„ธ์š”.

์ ‘๊ทผ๋ฒ•

ํ…”๋ ˆํฌํŠธ ์—†๋Š” ํ‘œ์ค€ DP

ํ…”๋ ˆํฌํŠธ๊ฐ€ ์—†์œผ๋ฉด ๋ฌธ์ œ๋Š” ๊ฐ„๋‹จํ•œ DP๋กœ ์ถ•์†Œ๋ฉ๋‹ˆ๋‹ค:

dp[i][j] = grid[i][j] + min(dp[iโ€‘1][j], dp[i][jโ€‘1])

ํ…”๋ ˆํฌํŠธ ๋„์ž…

ํ…”๋ ˆํฌํŠธ๋Š” ๋น„์šฉ์ด ๋“ค์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์— ๊ฐ•๋ ฅํ•˜์ง€๋งŒ, ํ˜„์žฌ ์…€์˜ ๊ฐ’๋ณด๋‹ค ํฌ์ง€ ์•Š์€ ์…€๋งŒ์„ ๋ชฉํ‘œ๋กœ ํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ, ์ตœ๋Œ€ k๋ฒˆ๋งŒ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์šฐ๋ฆฌ๋Š” ์ธต(๋˜๋Š” โ€œ๋ผ์šด๋“œโ€) ๋ณ„๋กœ ํ…”๋ ˆํฌํŠธ ์‚ฌ์šฉ ํšŸ์ˆ˜์— ๋”ฐ๋ผ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•ฉ๋‹ˆ๋‹ค:

  1. ํ…”๋ ˆํฌํŠธ ์‚ฌ์šฉ ํšŸ์ˆ˜ t = 0 โ€ฆ k๋งˆ๋‹ค ๋ชจ๋“  ๊ฐ€๋Šฅํ•œ ์…€ ๊ฐ’์— ๋„๋‹ฌํ•˜๋Š” ๊ฐ€์žฅ ์ €๋ ดํ•œ ๋น„์šฉ์„ ์œ ์ง€ํ•ฉ๋‹ˆ๋‹ค.
  2. ์ ‘๋ฏธ ์ตœ์†Œ ๋ฐฐ์—ด suf_min_f[value]๋Š” ๊ฐ’์ด โ‰ฅ value์ธ ์…€ ์ค‘ ๋„๋‹ฌ ๋น„์šฉ์ด ๊ฐ€์žฅ ๋‚ฎ์€ ๊ฐ’์„ ์ €์žฅํ•ฉ๋‹ˆ๋‹ค. ์ด๋ฅผ ํ†ตํ•ด โ€œ๊ฐ’์ด x์ธ ์…€๋กœ ํ…”๋ ˆํฌํŠธํ•˜๋Š” ๊ฒƒ์ด ๋” ์ €๋ ดํ•œ๊ฐ€?โ€๋ฅผ O(1)์— ๋‹ตํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  3. ๊ทธ๋ฆฌ๋“œ๋ฅผ ํ–‰โ€‘๋‹จ์œ„๋กœ ์Šค์บ”ํ•˜๋ฉด์„œ ๋‹ค์Œ์„ ์—…๋ฐ์ดํŠธํ•ฉ๋‹ˆ๋‹ค:
    • standard_move โ€“ ์™ผ์ชฝ ๋˜๋Š” ์œ„์ชฝ์—์„œ ์˜ค๋Š” ๋น„์šฉ์— ํ˜„์žฌ ์…€ ๊ฐ’์„ ๋”ํ•œ ๊ฐ’.
    • teleport_move โ€“ suf_min_f[x] (๊ฐ’์ด โ‰ฅ x์ธ ๋„๋‹ฌ ๊ฐ€๋Šฅํ•œ ์…€ ์ค‘ ๊ฐ€์žฅ ์ข‹์€ ๋น„์šฉ).
    • ์ด ๋‘ ๊ฐ’ ์ค‘ ์ตœ์†Œ๊ฐ€ ํ˜„์žฌ ์…€์˜ ์ƒˆ๋กœ์šด ๋น„์šฉ์ด ๋ฉ๋‹ˆ๋‹ค.
  4. ํŠน์ • t์— ๋Œ€ํ•ด ์ „์ฒด ๊ทธ๋ฆฌ๋“œ๋ฅผ ์ฒ˜๋ฆฌํ•œ ํ›„, ๋‹ค์Œ ๋ฐ˜๋ณต์„ ์œ„ํ•ด suf_min_f๋ฅผ ๋‹ค์‹œ ๊ตฌ์ถ•ํ•ฉ๋‹ˆ๋‹ค.

์•Œ๊ณ ๋ฆฌ์ฆ˜์€ suf_min_f๊ฐ€ ๋ฐ˜๋ณต ์‚ฌ์ด์— ๋ณ€ํ•˜์ง€ ์•Š์œผ๋ฉด ์กฐ๊ธฐ์— ์ข…๋ฃŒ๋ฉ๋‹ˆ๋‹ค.

๋ณต์žก๋„

  • ์‹œ๊ฐ„: O(k * m * n) โ€“ ๊ฐ ์ธต๋งˆ๋‹ค ๊ทธ๋ฆฌ๋“œ๋ฅผ ํ•œ ๋ฒˆ์”ฉ ์Šค์บ”ํ•ฉ๋‹ˆ๋‹ค.
  • ๊ณต๊ฐ„: O(mx + n) ์—ฌ๊ธฐ์„œ mx๋Š” ์…€ ๊ฐ’์˜ ์ตœ๋Œ€๊ฐ’(์ ‘๋ฏธ ๋ฐฐ์—ด์šฉ)์ด๋ฉฐ, ์„ ํ˜• DP ํ–‰์„ ์ถ”๊ฐ€๋กœ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

์˜ˆ์‹œ

grid = [[1,3,3],
        [2,5,4],
        [4,3,5]]
k = 2
  1. (0,0)์—์„œ ๋น„์šฉ 0์œผ๋กœ ์‹œ์ž‘ํ•ฉ๋‹ˆ๋‹ค.
  2. ์•„๋ž˜๋กœ ์ด๋™ํ•˜์—ฌ (1,0) โ†’ ๋น„์šฉ 2.
  3. ์˜ค๋ฅธ์ชฝ์œผ๋กœ ์ด๋™ํ•˜์—ฌ (1,1) โ†’ ๋น„์šฉ 7.
  4. (1,1) (๊ฐ’ 5)์—์„œ (2,2) (๊ฐ’ 5)๋กœ ๋ฌด๋ฃŒ ํ…”๋ ˆํฌํŠธํ•ฉ๋‹ˆ๋‹ค.
  5. ๋ชฉ์ ์ง€์— ๋„๋‹ฌํ–ˆ์œผ๋ฉฐ ์ด ๋น„์šฉ์€ 7์ž…๋‹ˆ๋‹ค.

๋‹ต์€ 7์ž…๋‹ˆ๋‹ค.

์†”๋ฃจ์…˜ ๊ตฌํ˜„

C++ (GNUโ€‘C++17)

class Solution {
public:
    int minCost(vector<vector<int>>& grid, int k) {
        int m = grid.size(), n = grid[0].size();

        // Edge case: free teleport possible
        if (k > 0 && grid[0][0] >= grid[m - 1][n - 1]) return 0;

        int mx = 0;
        for (auto& row : grid)
            for (int v : row) mx = max(mx, v);

        const int INF = 2e9;
        vector<int> suf_min_f(mx + 2, INF);
        vector<int> f(n + 1, INF);

        for (int t = 0; t <= k; ++t) {
            vector<int> min_f(mx + 1, INF);
            vector<int> new_f(n + 1, INF);
            if (t == 0) new_f[1] = 0;   // start cost

            for (int i = 0; i < m; ++i) {
                for (int j = 0; j < n; ++j) {
                    int x = grid[i][j];
                    int standard = min(new_f[j], new_f[j + 1]) + x;
                    if (i == 0 && j == 0 && t == 0) standard = 0;
                    new_f[j + 1] = min(standard, suf_min_f[x]);
                    min_f[x] = min(min_f[x], new_f[j + 1]);
                }
            }
            f = new_f;

            // rebuild suffix minima
            vector<int> new_suf(mx + 2, INF);
            for (int v = mx; v >= 0; --v)
                new_suf[v] = min(new_suf[v + 1], min_f[v]);

            if (suf_min_f == new_suf) break;
            suf_min_f.swap(new_suf);
        }
        return f[n];
    }
};

Python 3

class Solution:
    def minCost(self, grid: list[list[int]], k: int) -> int:
        m, n = len(grid), len(grid[0])
        if k > 0 and grid[0][0] >= grid[m - 1][n - 1]:
            return 0

        mx = max(max(row) for row in grid)
        INF = float('inf')
        suf_min_f = [INF] * (mx + 2)
        f = [INF] * (n + 1)

        for t in range(k + 1):
            min_f = [INF] * (mx + 1)
            new_f = [INF] * (n + 1)
            if t == 0:
                new_f[1] = 0   # start cost

            for i in range(m):
                for j in range(n):
                    x = grid[i][j]
                    standard = min(new_f[j], new_f[j + 1]) + x
                    if i == 0 and j == 0 and t == 0:
                        standard = 0
                    new_f[j + 1] = min(standard, suf_min_f[x])
                    min_f[x] = min(min_f[x], new_f[j + 1])

            f = new_f

            # rebuild suffix minima
            new_suf = [INF] * (mx + 2)
            for v in range(mx, -1, -1):
                new_suf[v] = min(new_suf[v + 1], min_f[v])

            if suf_min_f == new_suf:
                break
            suf_min_f = new_suf

        return f[n]

JavaScript (Node.js)

/**
 * @param {number[][]} grid
 * @param {number} k
 * @return {number}
 */
var minCost = function(grid, k) {
    const m = grid.length, n = grid[0].length;
    if (k > 0 && grid[0][0] >= grid[m - 1][n - 1]) return 0;

    let mx = 0;
    for (let row of grid)
        for (let v of row) mx = Math.max(mx, v);

    const INF = Number.MAX_SAFE_INTEGER;
    let sufMinF = new Array(mx + 2).fill(INF);
    let f = new Array(n + 1).fill(INF);

    for (let t = 0; t <= k; ++t) {
        const minF = new Array(mx + 1).fill(INF);
        const newF = new Array(n + 1).fill(INF);
        if (t === 0) newF[1] = 0;   // start cost

        for (let i = 0; i < m; ++i) {
            for (let j = 0; j < n; ++j) {
                const x = grid[i][j];
                const standard = Math.min(newF[j], newF[j + 1]) + x;
                const best = Math.min(standard, sufMinF[x]);
                newF[j + 1] = best;
                minF[x] = Math.min(minF[x], best);
            }
        }
        f = newF;

        // rebuild suffix minima
        const nextSuf = new Array(mx + 2).fill(INF);
        for (let v = mx; v >= 0; --v)
            nextSuf[v] = Math.min(nextSuf[v + 1], minF[v]);

        if (JSON.stringify(sufMinF) === JSON.stringify(nextSuf)) break;
        sufMinF = nextSuf;
    }
    return
f[n];
};

ํ•ต์‹ฌ ์š”์ 

  • ์ƒํƒœ ํ™•์žฅ (ํ…”๋ ˆํฌํŠธ ํšŸ์ˆ˜ ์ฐจ์›์„ ์ถ”๊ฐ€)์œผ๋กœ ๊ฐ ํ—ˆ์šฉ๋œ ํ…”๋ ˆํฌํŠธ๋งˆ๋‹ค ๋™์ผํ•œ DP ๋กœ์ง์„ ์žฌ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  • ์ ‘๋ฏธ ์ตœ์†Œ๊ฐ’์„ ์‚ฌ์šฉํ•˜๋ฉด โ€œ๊ฐ’์ด โ‰ฅโ€ฏx์ธ ๋ชจ๋“  ์…€ ์ค‘ ๊ฐ€์žฅ ์ €๋ ดํ•œ ๋น„์šฉโ€์— ๋Œ€ํ•ด O(1) ์กฐํšŒ๊ฐ€ ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค.
  • ๊ณต๊ฐ„ ์ตœ์ ํ™”: ์ด์ „ ํ…”๋ ˆํฌํŠธ ํšŸ์ˆ˜์˜ ๊ฒฐ๊ณผ๋งŒ ํ•„์š”ํ•˜๋ฏ€๋กœ ๋ฉ”๋ชจ๋ฆฌ ์‚ฌ์šฉ๋Ÿ‰์„ ์„ ํ˜•์œผ๋กœ ์œ ์ง€ํ•ฉ๋‹ˆ๋‹ค.

์ด ํŒจํ„ด์€ ๋ฐฐ๋‹ฌ ๋“œ๋ก ์ด (๋น„์šฉ์ด ๋งŽ์ด ๋“œ๋Š”) ์ง€์ƒ ์ฃผํ–‰์ด๋‚˜ ๊ณ ๊ณ ๋„ ํŒจ๋“œ ์‚ฌ์ด๋ฅผ (๋ฌด๋ฃŒ์ด์ง€๋งŒ ์ œํ•œ๋œ) ๋น„ํ–‰ํ•  ์ˆ˜ ์žˆ๋Š” ์‹ค์ œ ๋ผ์šฐํŒ… ๋ฌธ์ œ ๋“ฑ์—์„œ ๋งŽ์ด ๋‚˜ํƒ€๋‚ฉ๋‹ˆ๋‹ค.

Back to Blog

๊ด€๋ จ ๊ธ€

๋” ๋ณด๊ธฐ ยป

๐Ÿ›‚ ์ดˆ๋ณด์ž ์นœํ™” ๊ฐ€์ด๋“œ 'Divide an Array Into Subarrays With Minimum Cost II' - Problem 3013 (C++, Python, JavaScript)

๋ฌธ์ œ ๊ฐœ์š”: ๋ฐ์ดํ„ฐ๋ฅผ ์ตœ์  ๊ตฌ๊ฐ„์œผ๋กœ ๋‚˜๋ˆ„๋Š” ๊ฒƒ์€ ์ปดํ“จํ„ฐ ๊ณผํ•™์—์„œ ๊ณ ์ „์ ์ธ ๋„์ „ ๊ณผ์ œ๋กœ, ์ข…์ข… ํŠน์ • ์ œ์•ฝ๊ณผ ํšจ์œจ์„ฑ ์‚ฌ์ด์˜ ๊ท ํ˜•์„ ์š”๊ตฌํ•œ๋‹ค.

Mahdi Shamlou | LeetCode #7 ํ•ด๊ฒฐ: Reverse Integer โ€” ์˜ค๋ฒ„ํ”Œ๋กœ์šฐ ์•ˆ์ „์„ฑ์„ ๊ฐ–์ถ˜ ์ˆ˜ํ•™ ๊ธฐ๋ฐ˜ ์—ญ์ „

์—ฌ๋Ÿฌ๋ถ„, ์•ˆ๋…•ํ•˜์„ธ์š”! Mahdi Shamlou์ž…๋‹ˆ๋‹ค โ€” LeetCode ํด๋ž˜์‹ ๋ฌธ์ œ ์‹œ๋ฆฌ์ฆˆ๋ฅผ ๊ณ„์†ํ•ฉ๋‹ˆ๋‹ค ๐Ÿš€ 6๋ฒˆ์งธ Zigzag Conversion์„ ํ’€๊ณ , ์˜ค๋Š˜์€ Problem 7 โ€” Reverseโ€ฆ์— ๋„์ „ํ•ฉ๋‹ˆ๋‹ค.

LeetCode #347. ์ƒ์œ„ K ๋นˆ๋„ ์š”์†Œ

๋ณต์žก๋„ ๋ถ„์„ - ์‹œ๊ฐ„ ๋ณต์žก๋„: O(n log n), ์ •๋ ฌ์— ์˜ํ•ด ์ง€๋ฐฐ๋จ - ๊ณต๊ฐ„ ๋ณต์žก๋„: HashMap ๋ฐ List์— ๋Œ€ํ•ด O(n) Solution java class Solution { public int...