Skip to content

Commit 6cfb8ea

Browse files
authored
Add minimum cost path (#520)
1 parent 7f9f95c commit 6cfb8ea

File tree

2 files changed

+82
-0
lines changed

2 files changed

+82
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
/// Minimum Cost Path via Dynamic Programming
2+
3+
/// Find the minimum cost traced by all possible paths from top left to bottom right in
4+
/// a given matrix, by allowing only right and down movement
5+
6+
/// For example, in matrix,
7+
/// [2, 1, 4]
8+
/// [2, 1, 3]
9+
/// [3, 2, 1]
10+
/// The minimum cost path is 7
11+
12+
/// # Arguments:
13+
/// * `matrix` - The input matrix.
14+
/// # Complexity
15+
/// - time complexity: O( rows * columns ),
16+
/// - space complexity: O( rows * columns )
17+
use std::cmp::min;
18+
19+
pub fn minimum_cost_path(mut matrix: Vec<Vec<usize>>) -> usize {
20+
// Add rows and columns variables for better readability
21+
let rows = matrix.len();
22+
let columns = matrix[0].len();
23+
24+
// Preprocessing the first row
25+
for i in 1..columns {
26+
matrix[0][i] += matrix[0][i - 1];
27+
}
28+
29+
// Preprocessing the first column
30+
for i in 1..rows {
31+
matrix[i][0] += matrix[i - 1][0];
32+
}
33+
34+
// Updating path cost for the remaining positions
35+
// For each position, cost to reach it from top left is
36+
// Sum of value of that position and minimum of upper and left position value
37+
38+
for i in 1..rows {
39+
for j in 1..columns {
40+
matrix[i][j] += min(matrix[i - 1][j], matrix[i][j - 1]);
41+
}
42+
}
43+
44+
// Return cost for bottom right element
45+
matrix[rows - 1][columns - 1]
46+
}
47+
48+
#[cfg(test)]
49+
mod tests {
50+
use super::*;
51+
52+
#[test]
53+
fn basic() {
54+
// For test case in example
55+
let matrix = vec![vec![2, 1, 4], vec![2, 1, 3], vec![3, 2, 1]];
56+
assert_eq!(minimum_cost_path(matrix), 7);
57+
58+
// For a randomly generated matrix
59+
let matrix = vec![vec![1, 2, 3], vec![4, 5, 6]];
60+
assert_eq!(minimum_cost_path(matrix), 12);
61+
}
62+
63+
#[test]
64+
fn one_element_matrix() {
65+
let matrix = vec![vec![2]];
66+
assert_eq!(minimum_cost_path(matrix), 2);
67+
}
68+
69+
#[test]
70+
fn one_row() {
71+
let matrix = vec![vec![1, 3, 2, 1, 5]];
72+
assert_eq!(minimum_cost_path(matrix), 12);
73+
}
74+
75+
#[test]
76+
fn one_column() {
77+
let matrix = vec![vec![1], vec![3], vec![2], vec![1], vec![5]];
78+
assert_eq!(minimum_cost_path(matrix), 12);
79+
}
80+
}

src/dynamic_programming/mod.rs

+2
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ mod longest_increasing_subsequence;
1111
mod matrix_chain_multiply;
1212
mod maximal_square;
1313
mod maximum_subarray;
14+
mod minimum_cost_path;
1415
mod rod_cutting;
1516
mod snail;
1617
mod subset_generation;
@@ -35,6 +36,7 @@ pub use self::longest_increasing_subsequence::longest_increasing_subsequence;
3536
pub use self::matrix_chain_multiply::matrix_chain_multiply;
3637
pub use self::maximal_square::maximal_square;
3738
pub use self::maximum_subarray::maximum_subarray;
39+
pub use self::minimum_cost_path::minimum_cost_path;
3840
pub use self::rod_cutting::rod_cut;
3941
pub use self::snail::snail;
4042
pub use self::subset_generation::list_subset;

0 commit comments

Comments
 (0)