欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

C++實現(xiàn)LeetCode(64.最小路徑和)

 更新時間:2021年07月16日 16:14:54   作者:Grandyang  
這篇文章主要介紹了C++實現(xiàn)LeetCode(64.最小路徑和),本篇文章通過簡要的案例,講解了該項技術(shù)的了解與使用,以下就是詳細內(nèi)容,需要的朋友可以參考下

[LeetCode] 64. Minimum Path Sum 最小路徑和

Given a m x n grid filled with non-negative numbers, find a path from top left to bottom right which minimizes the sum of all numbers along its path.

Note: You can only move either down or right at any point in time.

Example:

Input:
[
[1,3,1],
[1,5,1],
[4,2,1]
]
Output: 7
Explanation: Because the path 1→3→1→1→1 minimizes the sum.

這道題給了我們一個只有非負數(shù)的二維數(shù)組,讓找一條從左上到右下的路徑,使得路徑和最小,限定了每次只能向下或者向右移動。一個常見的錯誤解法就是每次走右邊或下邊數(shù)字中較小的那個,這樣的貪婪算法獲得的局部最優(yōu)解不一定是全局最優(yōu)解,因此是不行的。實際上這道題跟之前那道 Dungeon Game 沒有什么太大的區(qū)別,都需要用動態(tài)規(guī)劃 Dynamic Programming 來做,這應該算是 DP 問題中比較簡單的一類,我們維護一個二維的 dp 數(shù)組,其中 dp[i][j] 表示到達當前位置的最小路徑和。接下來找狀態(tài)轉(zhuǎn)移方程,因為到達當前位置 (i, j)  只有兩種情況,要么從上方 (i-1, j) 過來,要么從左邊 (i, j-1) 過來,我們選擇 dp 值較小的那個路徑,即比較 dp[i-1][j] 和 dp[i][j-1],將其中的較小值加上當前的數(shù)字 grid[i][j],就是當前位置的 dp 值了。但是有些特殊情況要提前賦值,比如起點位置,直接賦值為 grid[0][0],還有就是第一行和第一列,其中第一行的位置只能從左邊過來,第一列的位置從能從上面過來,所以這兩行要提前初始化好,然后再從 (1, 1) 的位置開始更新到右下角即可,反正難度不算大,代碼如下:

解法一:

class Solution {
public:
    int minPathSum(vector<vector<int>>& grid) {
        if (grid.empty() || grid[0].empty()) return 0;
        int m = grid.size(), n = grid[0].size();
        vector<vector<int>> dp(m, vector<int>(n));
        dp[0][0] = grid[0][0];
        for (int i = 1; i < m; ++i) dp[i][0] = grid[i][0] + dp[i - 1][0];
        for (int j = 1; j < n; ++j) dp[0][j] = grid[0][j] + dp[0][j - 1];
        for (int i = 1; i < m; ++i) {
            for (int j = 1; j < n; ++j) {
                dp[i][j] = grid[i][j] + min(dp[i - 1][j], dp[i][j - 1]);
            }
        }
        return dp[m - 1][n - 1];
    }
};

我們可以優(yōu)化空間復雜度,可以使用一個一維的 dp 數(shù)組就可以了,初始化為整型最大值,但是 dp[0][0] 要初始化為0。之所以可以用一維數(shù)組代替之前的二維數(shù)組,是因為當前的 dp 值只跟左邊和上面的 dp 值有關(guān)。這里我們并不提前更新第一行或是第一列,而是在遍歷的時候判斷,若j等于0時,說明是第一列,我們直接加上當前的數(shù)字,否則就要比較是左邊的 dp[j-1] 小還是上面的 dp[j]  小,當是第一行的時候,dp[j] 是整型最大值,所以肯定會取到 dp[j-1] 的值,然后再加上當前位置的數(shù)字即可,參見代碼如下:

解法二:

class Solution {
public:
    int minPathSum(vector<vector<int>>& grid) {
        if (grid.empty() || grid[0].empty()) return 0;
        int m = grid.size(), n = grid[0].size();
        vector<int> dp(n, INT_MAX);
        dp[0] = 0;
        for (int i = 0; i < m; ++i) {
            for (int j = 0; j < n; ++j) {
                if (j == 0) dp[j] += grid[i][j];
                else dp[j] = grid[i][j] + min(dp[j], dp[j - 1]);
            }
        }
        return dp[n - 1];
    }
};

我們還可以進一步的優(yōu)化空間,連一維數(shù)組都不用新建,而是直接使用原數(shù)組 grid 進行累加,這里的累加方式跟解法一稍有不同,沒有提前對第一行和第一列進行賦值,而是放在一起判斷了,當i和j同時為0時,直接跳過。否則當i等于0時,只加上左邊的值,當j等于0時,只加上面的值,否則就比較左邊和上面的值,加上較小的那個即可,參見代碼如下:

解法三:

class Solution {
public:
    int minPathSum(vector<vector<int>>& grid) {
        if (grid.empty() || grid[0].empty()) return 0;
        for (int i = 0; i < grid.size(); ++i) {
            for (int j = 0; j < grid[i].size(); ++j) {
                if (i == 0 && j == 0) continue;
                if (i == 0) grid[0][j] += grid[0][j - 1];
                else if (j == 0) grid[i][0] += grid[i - 1][0];
                else grid[i][j] += min(grid[i - 1][j], grid[i][j - 1]);
            }
        }
        return grid.back().back();
    }
};

下面這種寫法跟上面的基本相同,只不過用了 up 和 left 兩個變量來計算上面和左邊的值,看起來稍稍簡潔一點,參見代碼如下:

解法四:

class Solution {
public:
    int minPathSum(vector<vector<int>>& grid) {
        if (grid.empty() || grid[0].empty()) return 0;
        for (int i = 0; i < grid.size(); ++i) {
            for (int j = 0; j < grid[i].size(); ++j) {
                if (i == 0 && j == 0) continue;
                int up = (i == 0) ? INT_MAX : grid[i - 1][j];
                int left = (j == 0) ? INT_MAX : grid[i][j - 1];
                grid[i][j] += min(up, left);
            }
        }
        return grid.back().back();
    }
};

到此這篇關(guān)于C++實現(xiàn)LeetCode(64.最小路徑和)的文章就介紹到這了,更多相關(guān)C++實現(xiàn)最小路徑和內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Qt實現(xiàn)UI界面純代碼示例

    Qt實現(xiàn)UI界面純代碼示例

    這篇文章主要給大家介紹了關(guān)于Qt實現(xiàn)UI界面的相關(guān)資料,使用Qt純代碼,實現(xiàn)了基本的界面,對大家學習或者使用Qt具有一定的參考借鑒價值,需要的朋友可以參考下
    2024-01-01
  • C++構(gòu)造析構(gòu)賦值運算函數(shù)應用詳解

    C++構(gòu)造析構(gòu)賦值運算函數(shù)應用詳解

    構(gòu)造函數(shù)主要作用在于創(chuàng)建對象時為對象的成員屬性賦值,構(gòu)造函數(shù)由編譯器自動調(diào)用,無須手動調(diào)用;析構(gòu)函數(shù)主要作用在于對象銷毀前系統(tǒng)自動調(diào)用,執(zhí)行一 些清理工作
    2022-09-09
  • C語言小游戲之簡易版三子棋(棋盤可自由擴展)

    C語言小游戲之簡易版三子棋(棋盤可自由擴展)

    這篇文章主要為大家詳細介紹了C語言實現(xiàn)三子棋游戲,還可以自由擴展棋盤大小,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-11-11
  • C++基于遞歸和非遞歸算法求二叉樹鏡像的方法

    C++基于遞歸和非遞歸算法求二叉樹鏡像的方法

    這篇文章主要介紹了C++基于遞歸和非遞歸算法求二叉樹鏡像的方法,針對二叉樹遍歷結(jié)合實例形式分析了遞歸與非遞歸算法的實現(xiàn)與使用技巧,需要的朋友可以參考下
    2017-05-05
  • C++實現(xiàn)希爾排序算法實例

    C++實現(xiàn)希爾排序算法實例

    大家好,本篇文章主要講的是C++實現(xiàn)希爾排序算法實例,感興趣的同學趕快來看一看吧,對你有幫助的話記得收藏一下,方便下次瀏覽
    2022-01-01
  • C++Vector容器常用函數(shù)接口詳解

    C++Vector容器常用函數(shù)接口詳解

    最近我學習了C++中的STL庫中的vector容器,對于常用容器,我們不僅要會使用其常用的函數(shù)接口,我們還有明白這些接口在其底層是如何實現(xiàn)的。所以特意整理出來一篇博客供我們學習
    2022-08-08
  • C語言如何讀取bmp圖像

    C語言如何讀取bmp圖像

    這篇文章主要介紹了C語言如何讀取bmp圖像,BMP即bitmap,由文件頭信息塊、圖像描述信息塊、顏色表、圖像數(shù)據(jù)區(qū)四部分組成,下文更多相關(guān)資料需要的小伙伴可以參考一下
    2022-04-04
  • 詳談浮點精度(float、double)運算不精確的原因

    詳談浮點精度(float、double)運算不精確的原因

    這篇文章主要介紹了詳談浮點精度(float、double)運算不精確的原因,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-12-12
  • C語言字符串函數(shù)模擬實現(xiàn)流程介紹

    C語言字符串函數(shù)模擬實現(xiàn)流程介紹

    字符串函數(shù)(String processing function)也叫字符串處理函數(shù),指的是編程語言中用來進行字符串處理的函數(shù),如C,pascal,Visual以及LotusScript中進行字符串拷貝,計算長度,字符查找等的函數(shù)
    2022-09-09
  • 解析之C++的列表初始化語法

    解析之C++的列表初始化語法

    有朋友在使用std::array時發(fā)現(xiàn)一個奇怪的問題:當元素類型是復合類型時,編譯通不過。按說std::array和原生數(shù)組的行為幾乎是一樣的,可為什么當元素類型不同時,初始化語法還會有差別?這篇文章會介紹這個問題的原理,以及正確的解決方式。
    2021-05-05

最新評論