From b70dd12d5ea80e0ec5ee151efb849f1e4fe7b984 Mon Sep 17 00:00:00 2001 From: wuaoxiang Date: Tue, 23 Jan 2024 22:47:21 +0800 Subject: [PATCH] solve minimum-falling-path-sum with cache of recursive --- src/dp/minimum_falling_path_sum.rs | 53 +++++++++++++++++++++++------- 1 file changed, 42 insertions(+), 11 deletions(-) diff --git a/src/dp/minimum_falling_path_sum.rs b/src/dp/minimum_falling_path_sum.rs index cba93f4..047d7eb 100644 --- a/src/dp/minimum_falling_path_sum.rs +++ b/src/dp/minimum_falling_path_sum.rs @@ -1,32 +1,63 @@ //! https://leetcode.cn/problems/minimum-falling-path-sum + +/* +here is a leetcode question: Given an n x n array of integers matrix, return the minimum sum of any falling path through matrix. + +A falling path starts at any element in the first row and chooses the element in the next row that is either directly below or diagonally left/right. Specifically, the next element from position (row, col) will be (row + 1, col - 1), (row + 1, col), or (row + 1, col + 1). + +below is my Rust code, pass 70/100 test case but time limit exceed + +I don't know how to solve this problem using dynamtic programing + +but I have a optimize idea is add a cache arg in search function, to cache each input/output of search, can you help me to impl it? +*/ + +/// time limit exceed fn min_falling_path_sum(matrix: Vec>) -> i32 { let m = matrix.len(); let n = matrix[0].len(); + let mut cache = vec![vec![None; n]; m]; // Create a cache with the same dimensions as matrix let mut min = i32::MAX; for j in 0..n { - min = min.min(search(0, j, m, n, 0, &matrix)); + min = min.min(search(0, j, &matrix, &mut cache)); } min } -fn search(row: usize, col:usize, m: usize, n: usize, mut sum: i32, matrix: &Vec>) -> i32 { - if row == m { - return sum; +fn search(row: usize, col: usize, matrix: &Vec>, cache: &mut Vec>>) -> i32 { + if row == matrix.len() { + return 0; // We've reached the bottom of the matrix, no more values to add } + + // If we have a cached value, return it + if let Some(cached) = cache[row][col] { + return cached; + } + let cur_val = matrix[row][col]; - sum += cur_val; - let mut min = search(row+1,col, m, n, sum, matrix); - if col >= 1 { - min = min.min(search(row+1,col-1, m, n, sum, matrix)); + let mut min_path = cur_val + search(row + 1, col, matrix, cache); // Vertical + + if col > 0 { + min_path = min_path.min(cur_val + search(row + 1, col - 1, matrix, cache)); // Diagonally left } - if col < n-1 { - min = min.min(search(row+1,col+1, m, n, sum, matrix)); + if col + 1 < matrix[0].len() { + min_path = min_path.min(cur_val + search(row + 1, col + 1, matrix, cache)); // Diagonally right } - min + + // Store the result in the cache before returning + cache[row][col] = Some(min_path); + min_path } +/* +## DP solution +assume m,j is rows,columns of matrix +answer = min(sum[m-1][0], sum[m-1][1], ..., sum[m-1][n-1]) +sum[m-1][0]=matrix[m-1][0] + min(sum[m-2][0], sum[m-2][1]) +*/ + #[test] fn test() { for (matrix, min_path_sum) in [