Welcome to Subscribe On Youtube
3651. Minimum Cost Path with Teleportations
Description
You are given a m x n 2D integer array grid and an integer k. You start at the top-left cell (0, 0) and your goal is to reach the bottom‐right cell (m - 1, n - 1).
There are two types of moves available:
-
Normal move: You can move right or down from your current cell
(i, j), i.e. you can move to(i, j + 1)(right) or(i + 1, j)(down). The cost is the value of the destination cell. -
Teleportation: You can teleport from any cell
(i, j), to any cell(x, y)such thatgrid[x][y] <= grid[i][j]; the cost of this move is 0. You may teleport at mostktimes.
Return the minimum total cost to reach cell (m - 1, n - 1) from (0, 0).
Example 1:
Input: grid = [[1,3,3],[2,5,4],[4,3,5]], k = 2
Output: 7
Explanation:
Initially we are at (0, 0) and cost is 0.
| Current Position | Move | New Position | Total Cost |
|---|---|---|---|
(0, 0) |
Move Down | (1, 0) |
0 + 2 = 2 |
(1, 0) |
Move Right | (1, 1) |
2 + 5 = 7 |
(1, 1) |
Teleport to (2, 2) |
(2, 2) |
7 + 0 = 7 |
The minimum cost to reach bottom-right cell is 7.
Example 2:
Input: grid = [[1,2],[2,3],[3,4]], k = 1
Output: 9
Explanation:
Initially we are at (0, 0) and cost is 0.
| Current Position | Move | New Position | Total Cost |
|---|---|---|---|
(0, 0) |
Move Down | (1, 0) |
0 + 2 = 2 |
(1, 0) |
Move Right | (1, 1) |
2 + 3 = 5 |
(1, 1) |
Move Down | (2, 1) |
5 + 4 = 9 |
The minimum cost to reach bottom-right cell is 9.
Constraints:
2 <= m, n <= 80m == grid.lengthn == grid[i].length0 <= grid[i][j] <= 1040 <= k <= 10
Solutions
Solution 1
-
class Solution { public int minCost(int[][] grid, int k) { int m = grid.length, n = grid[0].length; int inf = Integer.MAX_VALUE / 2; int[][][] f = new int[k + 1][m][n]; for (int t = 0; t <= k; t++) { for (int i = 0; i < m; i++) { Arrays.fill(f[t][i], inf); } } f[0][0][0] = 0; for (int i = 0; i < m; i++) { for (int j = 0; j < n; j++) { if (i > 0) { f[0][i][j] = Math.min(f[0][i][j], f[0][i - 1][j] + grid[i][j]); } if (j > 0) { f[0][i][j] = Math.min(f[0][i][j], f[0][i][j - 1] + grid[i][j]); } } } Map<Integer, List<int[]>> g = new HashMap<>(); for (int i = 0; i < m; i++) { for (int j = 0; j < n; j++) { int x = grid[i][j]; g.computeIfAbsent(x, z -> new ArrayList<>()).add(new int[] {i, j}); } } List<Integer> keys = new ArrayList<>(g.keySet()); keys.sort(Collections.reverseOrder()); for (int t = 1; t <= k; t++) { int mn = inf; for (int key : keys) { List<int[]> pos = g.get(key); for (int[] p : pos) { mn = Math.min(mn, f[t - 1][p[0]][p[1]]); } for (int[] p : pos) { f[t][p[0]][p[1]] = mn; } } for (int i = 0; i < m; i++) { for (int j = 0; j < n; j++) { if (i > 0) { f[t][i][j] = Math.min(f[t][i][j], f[t][i - 1][j] + grid[i][j]); } if (j > 0) { f[t][i][j] = Math.min(f[t][i][j], f[t][i][j - 1] + grid[i][j]); } } } } int ans = inf; for (int t = 0; t <= k; t++) { ans = Math.min(ans, f[t][m - 1][n - 1]); } return ans; } } -
class Solution { public: int minCost(vector<vector<int>>& grid, int k) { int m = grid.size(), n = grid[0].size(); int inf = INT_MAX / 2; vector<vector<vector<int>>> f(k + 1, vector<vector<int>>(m, vector<int>(n, inf))); f[0][0][0] = 0; for (int i = 0; i < m; i++) { for (int j = 0; j < n; j++) { if (i > 0) { f[0][i][j] = min(f[0][i][j], f[0][i - 1][j] + grid[i][j]); } if (j > 0) { f[0][i][j] = min(f[0][i][j], f[0][i][j - 1] + grid[i][j]); } } } unordered_map<int, vector<pair<int, int>>> g; for (int i = 0; i < m; i++) { for (int j = 0; j < n; j++) { int x = grid[i][j]; g[x].push_back({i, j}); } } vector<int> keys; keys.reserve(g.size()); for (auto& e : g) { keys.push_back(e.first); } sort(keys.begin(), keys.end(), greater<int>()); for (int t = 1; t <= k; t++) { int mn = inf; for (int key : keys) { auto& pos = g[key]; for (auto& p : pos) { mn = min(mn, f[t - 1][p.first][p.second]); } for (auto& p : pos) { f[t][p.first][p.second] = mn; } } for (int i = 0; i < m; i++) { for (int j = 0; j < n; j++) { if (i > 0) { f[t][i][j] = min(f[t][i][j], f[t][i - 1][j] + grid[i][j]); } if (j > 0) { f[t][i][j] = min(f[t][i][j], f[t][i][j - 1] + grid[i][j]); } } } } int ans = inf; for (int t = 0; t <= k; t++) { ans = min(ans, f[t][m - 1][n - 1]); } return ans; } }; -
class Solution: def minCost(self, grid: List[List[int]], k: int) -> int: m, n = len(grid), len(grid[0]) f = [[[inf] * n for _ in range(m)] for _ in range(k + 1)] f[0][0][0] = 0 for i in range(m): for j in range(n): if i: f[0][i][j] = min(f[0][i][j], f[0][i - 1][j] + grid[i][j]) if j: f[0][i][j] = min(f[0][i][j], f[0][i][j - 1] + grid[i][j]) g = defaultdict(list) for i, row in enumerate(grid): for j, x in enumerate(row): g[x].append((i, j)) keys = sorted(g, reverse=True) for t in range(1, k + 1): mn = inf for key in keys: pos = g[key] for i, j in pos: mn = min(mn, f[t - 1][i][j]) for i, j in pos: f[t][i][j] = mn for i in range(m): for j in range(n): if i: f[t][i][j] = min(f[t][i][j], f[t][i - 1][j] + grid[i][j]) if j: f[t][i][j] = min(f[t][i][j], f[t][i][j - 1] + grid[i][j]) return min(f[t][m - 1][n - 1] for t in range(k + 1)) -
func minCost(grid [][]int, k int) int { m, n := len(grid), len(grid[0]) inf := int(^uint(0)>>1) / 4 f := make([][][]int, k+1) for t := 0; t <= k; t++ { f[t] = make([][]int, m) for i := 0; i < m; i++ { f[t][i] = make([]int, n) for j := 0; j < n; j++ { f[t][i][j] = inf } } } f[0][0][0] = 0 for i := 0; i < m; i++ { for j := 0; j < n; j++ { if i > 0 { f[0][i][j] = min(f[0][i][j], f[0][i-1][j]+grid[i][j]) } if j > 0 { f[0][i][j] = min(f[0][i][j], f[0][i][j-1]+grid[i][j]) } } } g := make(map[int][][]int) for i := 0; i < m; i++ { for j := 0; j < n; j++ { x := grid[i][j] g[x] = append(g[x], []int{i, j}) } } keys := make([]int, 0, len(g)) for key := range g { keys = append(keys, key) } sort.Sort(sort.Reverse(sort.IntSlice(keys))) for t := 1; t <= k; t++ { mn := inf for _, key := range keys { pos := g[key] for _, p := range pos { mn = min(mn, f[t-1][p[0]][p[1]]) } for _, p := range pos { f[t][p[0]][p[1]] = mn } } for i := 0; i < m; i++ { for j := 0; j < n; j++ { if i > 0 { f[t][i][j] = min(f[t][i][j], f[t][i-1][j]+grid[i][j]) } if j > 0 { f[t][i][j] = min(f[t][i][j], f[t][i][j-1]+grid[i][j]) } } } } ans := inf for t := 0; t <= k; t++ { ans = min(ans, f[t][m-1][n-1]) } return ans } -
function minCost(grid: number[][], k: number): number { const [m, n] = [grid.length, grid[0].length]; const INF = 1e18; const f: number[][][] = Array.from({ length: k + 1 }, () => Array.from({ length: m }, () => Array(n).fill(INF)), ); f[0][0][0] = 0; for (let i = 0; i < m; i++) { for (let j = 0; j < n; j++) { if (i > 0) f[0][i][j] = Math.min(f[0][i][j], f[0][i - 1][j] + grid[i][j]); if (j > 0) f[0][i][j] = Math.min(f[0][i][j], f[0][i][j - 1] + grid[i][j]); } } const g = new Map<number, Array<[number, number]>>(); for (let i = 0; i < m; i++) { for (let j = 0; j < n; j++) { const x = grid[i][j]; if (!g.has(x)) { g.set(x, []); } g.get(x)!.push([i, j]); } } const keys = Array.from(g.keys()).sort((a, b) => b - a); for (let t = 1; t <= k; t++) { let mn = INF; for (const key of keys) { const pos = g.get(key)!; for (const [x, y] of pos) { mn = Math.min(mn, f[t - 1][x][y]); } for (const [x, y] of pos) { f[t][x][y] = mn; } } for (let i = 0; i < m; i++) { for (let j = 0; j < n; j++) { if (i > 0) { f[t][i][j] = Math.min(f[t][i][j], f[t][i - 1][j] + grid[i][j]); } if (j > 0) { f[t][i][j] = Math.min(f[t][i][j], f[t][i][j - 1] + grid[i][j]); } } } } let ans = INF; for (let t = 0; t <= k; t++) { ans = Math.min(ans, f[t][m - 1][n - 1]); } return ans; } -
use std::collections::HashMap; impl Solution { pub fn min_cost(grid: Vec<Vec<i32>>, k: i32) -> i32 { let m = grid.len(); let n = grid[0].len(); let k = k as usize; let inf: i32 = i32::MAX / 2; let mut f = vec![vec![vec![inf; n]; m]; k + 1]; f[0][0][0] = 0; for i in 0..m { for j in 0..n { if i > 0 { f[0][i][j] = f[0][i][j].min(f[0][i - 1][j] + grid[i][j]); } if j > 0 { f[0][i][j] = f[0][i][j].min(f[0][i][j - 1] + grid[i][j]); } } } let mut g: HashMap<i32, Vec<(usize, usize)>> = HashMap::new(); for i in 0..m { for j in 0..n { g.entry(grid[i][j]).or_default().push((i, j)); } } let mut keys: Vec<i32> = g.keys().cloned().collect(); keys.sort_by(|a, b| b.cmp(a)); for t in 1..=k { let mut mn = inf; for &key in &keys { let pos = &g[&key]; for &(i, j) in pos { mn = mn.min(f[t - 1][i][j]); } for &(i, j) in pos { f[t][i][j] = mn; } } for i in 0..m { for j in 0..n { if i > 0 { f[t][i][j] = f[t][i][j].min(f[t][i - 1][j] + grid[i][j]); } if j > 0 { f[t][i][j] = f[t][i][j].min(f[t][i][j - 1] + grid[i][j]); } } } } let mut ans = inf; for t in 0..=k { ans = ans.min(f[t][m - 1][n - 1]); } ans } }