最小路径和

165 阅读1分钟

需求

找左上到右下的最小路径,输出路径和,只能右or下移动

输入:[[1, 3, 1], [1, 5, 1], [4, 2, 1]]
输出:7
路径是:1-3-1-1-1

思路

二维数组转矩阵,得到具象结构

[131151421]\begin{bmatrix} 1 & 3 & 1 \\ 1 & 5 & 1 \\ 4 & 2 & 1 \end{bmatrix}

用动态规划,将从 1 到 n 的问题转为 n-1 到 n 的问题 于是得到关键两步

  • n 的最短路径是 n-1 的最短路径 + n 本身的最短路径
  • 1 的最短路径是数据本身

随后将上述数据转换为需求数据(路径和)

[145276687]\begin{bmatrix} 1 & 4 & 5 \\ 2 & 7 & 6 \\ 6 & 8 & 7 \end{bmatrix}

这样由最后一个数据可知最短路径为 7

解法

/**
 * 最小路径和
 * input: [[1, 3, 1], [1, 5, 1], [4, 2, 1]]
 * output: 7
 * @param arr 
 */
const minPath = (arr) => {
    // to grid
    const r = arr.length;
    const c = arr[0].length;
    const _arr = Array.from({length:r}, () => Array(c).fill(0))
    // fill base data
    for(let _r = 0; _r < r; _r++) {
       _arr[_r][0] = _r === 0 ? arr[_r][0] : _arr[_r-1][0] + arr[_r][0];
    }
    for(let _c = 0; _c < c; _c++) {
       _arr[0][_c] = _c === 0 ? arr[0][_c] : _arr[0][_c-1] + arr[0][_c];
    }
    // fill others data
    for(let _r = 1; _r < r; _r++) {
       for(let _c = 1; _c < c; _c++) {
          _arr[_r][_c] = Math.min(_arr[_r-1][_c], _arr[_r][_c-1]) + arr[_r][_c]
       }
    }
    return _arr[r-1][c-1]
}
// test
const data1 = [[1, 3, 1], [1, 5, 1], [4, 2, 1]];
const data2 = [[1, 2, 3], [4, 5, 6]];
console.log(minPath(data1))  // 7
console.log(minPath(data2))  // 12