Skip to content

Commit ba781c0

Browse files
authored
feat: added [algo-04] (#13)
* feat: added c++ solution * feat: added go solution * feat: added python solution * feat: added rust solution * feat: added ts solution * fix: linting
1 parent 2015690 commit ba781c0

File tree

12 files changed

+203
-10
lines changed

12 files changed

+203
-10
lines changed

PROBLEMS.md

+20-1
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ NOTE: it can also be solved by traversing the tree in-order.
4646
**Auxiliary space:** `O(1)` -> The extra space is constant
4747

4848

49-
## `[algo-03]` Longest Substring Without Repeating Characters
49+
## `[algo-03]` Longest Substring Without Repeating Characters `[medium]`
5050

5151
Problem description can be found at [leetcode](https://leetcode.com/problems/longest-substring-without-repeating-characters/)
5252

@@ -64,3 +64,22 @@ E.g.
6464

6565
**Time Complexity:** `O(n)` -> We iterate the whole string
6666
**Auxiliary space:** `O(1)` -> The extra space is the number of characters in `[a-z]`
67+
68+
## `[algo-04]` Minimim Path Sum `[medium]`
69+
70+
Problem description can be found at [leetcode](https://leetcode.com/problems/minimum-path-sum/)
71+
72+
### Solution
73+
74+
This is a weighted vertice graph problem. A solution doing DFS would be valid but the runtime would be O(2^(n+m)).
75+
When calculating a `minPath` on a node, we know that: `minCost[i][j] = matrix[i][j] + min(minCost[i-1][j], minCost[i][j-1])`.
76+
So, for each node, the minPath at that point is the minimum between the path until the node on the top and the path until the node to the left.
77+
With that in mind, we can **pre-fill** our matrix of costs on the first row and first column.
78+
Steps:
79+
- Pre-fill first column and row
80+
- Iterate over the matrix and fill the rest of cells knowing that `minCost[i][j] = matrix[i][j] + min(minCost[i-1][j], minCost[i][j-1])`.
81+
82+
**Time Complexity:** `O(m * n)` -> We visit all the cells in the matrix
83+
**Auxiliary space:** `O(m * n)` -> We store the cost of all the cells
84+
85+
+31
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
#include <gtest/gtest.h>
2+
#include <vector>
3+
4+
using namespace std;
5+
6+
int min_path_sum(vector<vector<int>> &grid) {
7+
const int m = grid.size();
8+
const int n = grid[0].size();
9+
vector<vector<int>> costs(m, vector<int>(n, 0));
10+
11+
costs[0][0] = grid[0][0];
12+
13+
for (int i = 1; i < m; i++) {
14+
costs[i][0] = grid[i][0] + costs[i - 1][0];
15+
}
16+
for (int i = 1; i < n; i++) {
17+
costs[0][i] = grid[0][i] + costs[0][i - 1];
18+
}
19+
20+
for (int i = 1; i < m; i++) {
21+
for (int j = 1; j < n; j++) {
22+
costs[i][j] = grid[i][j] + min(costs[i - 1][j], costs[i][j - 1]);
23+
}
24+
}
25+
return costs[m - 1][n - 1];
26+
}
27+
28+
TEST(MinPathSum, Test) {
29+
vector<vector<int>> input = {{1, 3, 1}, {1, 5, 1}, {4, 2, 1}};
30+
ASSERT_EQ(min_path_sum(input), 7);
31+
}

packages/algo-go/solutions/algo-04.go

+30
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
package solutions
2+
3+
func MinPathSum(grid [][]int) int {
4+
m, n := len(grid), len(grid[0])
5+
costs := make([][]int, m)
6+
for i := range costs {
7+
costs[i] = make([]int, n)
8+
}
9+
costs[0][0] = grid[0][0]
10+
11+
for i := 1; i < m; i++ {
12+
costs[i][0] = grid[i][0] + costs[i-1][0]
13+
}
14+
for i := 1; i < n; i++ {
15+
costs[0][i] = grid[0][i] + costs[0][i-1]
16+
}
17+
for i := 1; i < m; i++ {
18+
for j := 1; j < n; j++ {
19+
costs[i][j] = grid[i][j] + min(costs[i-1][j], costs[i][j-1])
20+
}
21+
}
22+
return costs[m-1][n-1]
23+
}
24+
25+
func min(a, b int) int {
26+
if a < b {
27+
return a
28+
}
29+
return b
30+
}
+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
package solutions
2+
3+
import "testing"
4+
5+
func TestMinPathSum(t *testing.T) {
6+
input := [][]int{
7+
{1, 3, 1},
8+
{1, 5, 1},
9+
{4, 2, 1},
10+
}
11+
12+
if MinPathSum(input) != 7 {
13+
t.Error("Failed")
14+
}
15+
}

packages/algo-py/solutions/__init__.py

+1
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,4 @@
22
from .algo_01 import *
33
from .algo_02 import *
44
from .algo_03 import *
5+
from .algo_04 import *

packages/algo-py/solutions/algo_04.py

+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
def min_path_sum(grid):
2+
m = len(grid)
3+
n = len(grid[0])
4+
costs = [[0 for _ in range(n)] for _ in range(m)]
5+
costs[0][0] = grid[0][0]
6+
for i in range(1, m):
7+
costs[i][0] = grid[i][0] + costs[i-1][0]
8+
for j in range(1, n):
9+
costs[0][j] = grid[0][j] + costs[0][j-1]
10+
for i in range(1, m):
11+
for j in range(1, n):
12+
costs[i][j] = grid[i][j] + min(costs[i-1][j], costs[i][j-1])
13+
14+
return costs[m-1][n-1]
+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import unittest
2+
from solutions import min_path_sum
3+
4+
5+
class TestAlgo_04(unittest.TestCase):
6+
def test(self):
7+
input = [
8+
[1,3,1],
9+
[1,5,1],
10+
[4,2,1],
11+
]
12+
self.assertEqual(min_path_sum(input), 7)
13+
14+
15+
if __name__ == '__main__':
16+
unittest.main()

packages/algo-rust/src/algo_03.rs

+9-9
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,17 @@
11
use std::cmp;
22

33
fn max_substr(input: String) -> i32 {
4-
let mut max = 0;
5-
let mut start = 0;
6-
let mut indexes = arr![-1; 127];
4+
let mut max: i32 = 0;
5+
let mut start: i32 = 0;
6+
let mut indexes = vec![-1; 127];
77
for (i, c) in input.chars().enumerate() {
8-
if indexes[c] >= start {
9-
start = indexes[c] + 1;
8+
if indexes[c as usize] >= start {
9+
start = indexes[c as usize] + 1;
1010
}
11-
indexes[c] = i;
12-
max = cmp::max(max, i - start + 1);
11+
indexes[c as usize] = i as i32;
12+
max = cmp::max(max, (i as i32) - start + 1);
1313
}
14-
return max;
14+
max
1515
}
1616

1717
#[cfg(test)]
@@ -21,6 +21,6 @@ mod test {
2121
#[test]
2222
fn test() {
2323
let input = "abcbghjb";
24-
assert_eq!(max_substr(input), 5);
24+
assert_eq!(max_substr(input.to_string()), 5);
2525
}
2626
}

packages/algo-rust/src/algo_04.rs

+33
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
use std::cmp;
2+
3+
fn min_path_sum(grid: Vec<Vec<i32>>) -> i32 {
4+
let (m, n) = (grid.len(), grid[0].len());
5+
let mut costs = vec![vec![0_i32; n]; m];
6+
costs[0][0] = grid[0][0];
7+
8+
for i in 1..m {
9+
costs[i][0] = grid[i][0] + costs[i - 1][0];
10+
}
11+
for j in 1..n {
12+
costs[0][j] = grid[0][j] + costs[0][j - 1];
13+
}
14+
15+
for i in 1..m {
16+
for j in 1..n {
17+
costs[i][j] = grid[i][j] + cmp::min(costs[i - 1][j], costs[i][j - 1]);
18+
}
19+
}
20+
21+
costs[m - 1][n - 1]
22+
}
23+
24+
#[cfg(test)]
25+
mod test {
26+
use super::*;
27+
28+
#[test]
29+
fn test() {
30+
let input = vec![vec![1, 3, 1], vec![1, 5, 1], vec![4, 2, 1]];
31+
assert_eq!(min_path_sum(input), 7);
32+
}
33+
}

packages/algo-rust/src/lib.rs

+2
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,5 @@
44
mod algo_00;
55
mod algo_01;
66
mod algo_02;
7+
mod algo_03;
8+
mod algo_04;

packages/algo-ts/src/algo_04.ts

+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
export function MinPathSum(grid: number[][]): number {
2+
const m = grid.length;
3+
const n = grid[0].length;
4+
const costs = Array.from(Array(m), () => new Array(n));
5+
6+
costs[0][0] = grid[0][0];
7+
for (let i = 1; i < m; i++) {
8+
costs[i][0] = grid[i][0] + costs[i - 1][0];
9+
}
10+
for (let j = 1; j < n; j++) {
11+
costs[0][j] = grid[0][j] + costs[0][j - 1];
12+
}
13+
for (let i = 1; i < m; i++) {
14+
for (let j = 1; j < n; j++) {
15+
costs[i][j] = grid[i][j] + Math.min(costs[i - 1][j], costs[i][j - 1]);
16+
}
17+
}
18+
return costs[m - 1][n - 1];
19+
}
20+

packages/algo-ts/test/algo_04.spec.ts

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
import {MinPathSum} from "$/algo_04";
2+
3+
describe("algo-04", () => {
4+
it("should find the minimum path", () => {
5+
const input = [
6+
[1, 3, 1],
7+
[1, 5, 1],
8+
[4, 2, 1],
9+
];
10+
expect(MinPathSum(input)).toEqual((7))
11+
});
12+
});

0 commit comments

Comments
 (0)