1. 程式人生 > 其它 >Qt練手——計算圓面積和計算器(不含括號)

Qt練手——計算圓面積和計算器(不含括號)

技術標籤:LeetCode

64. 最小路徑和

題目描述

給定一個包含非負整數的 m x n 網格 grid ,請找出一條從左上角到右下角的路徑,使得路徑上的數字總和為最小。

**說明:**每次只能向下或者向右移動一步。

示例1:
在這裡插入圖片描述

輸入:grid = [[1,3,1],[1,5,1],[4,2,1]]
輸出:7
解釋:因為路徑 1→3→1→1→1 的總和最小。

示例 2:

輸入:grid = [[1,2,3],[4,5,6]]
輸出:12

提示:

  • m == grid.length

  • n == grid[i].length

  • 1 ≤ m , n ≤ 200 1 \le m, n \le 200

    1m,n200

  • 0 ≤ g r i d [ i ] [ j ] ≤ 100 0 \le grid[i][j] \le 100 0grid[i][j]100


題解:

動態規劃。

f[i][j] 表示從 (0,0) 走到 (i,j) 路徑上的數字最小和,轉移方程為:f[i][j] = min{f[i - 1][j], f[i][j - 1]} + grid[i][j]

注意特殊處理第一行和第一列。

時間複雜度: O ( n ∗ m ) O(n*m) O(nm)

額外空間複雜度:有三種寫法:

寫法一:

額外空間複雜度: O ( 1 ) O(1) O(1)

直接把 grid 陣列當做 f ,在上面更新,算是耍賴了哈哈哈哈。

class Solution {
public:
    int minPathSum(vector<vector<int>>& grid) {
        int n = grid.size();
        int m = grid[0].size();
        for ( int i = 0; i < n; ++i ) {
            for ( int j = 0; j < m; ++j ) {
                if ( i && j )
                    grid[
i][j] += min( grid[i - 1][j], grid[i][j - 1] ); else if ( i ) grid[i][j] += grid[i - 1][j]; else if ( j ) grid[i][j] += grid[i][j - 1]; } } return grid[n - 1][m - 1]; } }; /* 時間:8ms,擊敗:98.15% 記憶體:9.3MB,擊敗:99.22% */

寫法二:

額外空間複雜度: O ( n ∗ m ) O(n*m) O(nm)

正兒八經的開闢一個二維陣列 f,計算過程和 寫法一 一致。

class Solution {
public:
    int minPathSum(vector<vector<int>>& grid) {
        int n = grid.size();
        int m = grid[0].size();
        vector<vector<int>> f( n, vector<int>(m) );
        for ( int i = 0; i < n; ++i ) {
            for ( int j = 0; j < m; ++j ) {
                f[i][j] = grid[i][j];
                if ( i && j ) f[i][j] += min( f[i - 1][j], f[i][j - 1] );
                else if ( i ) f[i][j] += f[i - 1][j];
                else if ( j ) f[i][j] += f[i][j - 1];
            }
        }
        return f[n - 1][m - 1];
    }
};
/*
時間:12ms,擊敗:93.80%
記憶體:9.7MB,擊敗:92.90%
*/

寫法三:

寫法二 中,f[i][j] 只跟 f[i][...]f[i-1][...] 有關,可使用滾動陣列優化。

額外空間複雜度: O ( m ) O(m) O(m)

class Solution {
public:
    int minPathSum(vector<vector<int>>& grid) {
        int n = grid.size();
        int m = grid[0].size();
        vector<int> f(m);
        int pre;
        for ( int i = 0; i < n; ++i ) {
            for ( int j = 0; j < m; ++j ) {
                pre = f[j];
                f[j] = grid[i][j];
                if ( i && j ) f[j] += min( pre, f[j - 1] );
                else if ( i ) f[j] += pre;
                else if ( j ) f[j] += f[j - 1];
            }
        }
        return f[m - 1];
    }
};
/*
時間:8ms,擊敗:98.15%
記憶體:9.4MB,擊敗:97.16%
*/