動態規划小結 - 二維動態規划 - 時間復雜度 O(n*n)的棋盤型,題 [LeetCode] Minimum Path Sum,Unique Paths II,Edit Distance


引言

二維動態規划中最常見的是棋盤型二維動態規划。

func(i, j) 往往只和 func(i-1, j-1), func(i-1, j) 以及 func(i, j-1) 有關

這種情況下,時間復雜度 O(n*n),空間復雜度往往可以優化為O(n)

 

例題  1

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.

時間復雜度 O(n*n),空間復雜度O(n)的解法。

這里用了個以前不用的技巧,當想把數組初始化為非0的值時,不用memset,而改用vector表示數組。

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

 

 

例題  2

Unique Paths II

A robot is located at the top-left corner of a m x n grid (marked 'Start' in the diagram below).

The robot can only move either down or right at any point in time. The robot is trying to reach the bottom-right corner of the grid (marked 'Finish' in the diagram below).

Above is a 3 x 7 grid. How many possible unique paths are there?

Now consider if some obstacles are added to the grids. How many unique paths would there be?

An obstacle and empty space is marked as 1 and 0 respectively in the grid.

For example,

There is one obstacle in the middle of a 3x3 grid as illustrated below.

[
  [0,0,0],
  [0,1,0],
  [0,0,0]
]

The total number of unique paths is 2.

Note: m and n will be at most 100.

 

時間復雜度 O(n*n),空間復雜度O(n)

class Solution {
public:
    int uniquePathsWithObstacles(vector<vector<int> > &obstacleGrid) {
        if(obstacleGrid.size() == 0 || obstacleGrid[0].size() == 0) return 0;
        int H = obstacleGrid.size(), W = obstacleGrid[0].size();
        int paths[W+1]; memset(paths, 0, sizeof(paths));
        paths[1] = (obstacleGrid[0][0] ? 0 : 1);
        for(int i = 1; i <= H; ++i){
            for(int j = 1; j <= W; ++j){
                paths[j] = (obstacleGrid[i-1][j-1] ? 0 : paths[j-1] + paths[j]);
            }
        }
        return paths[W];
    }
};

 

 

例題  3

很熟悉的 Edit Distance

Given two words word1 and word2, find the minimum number of steps required to convert word1 to word2. (each operation is counted as 1 step.)

You have the following 3 operations permitted on a word:

a) Insert a character
b) Delete a character
c) Replace a character

類似的還有http://basicalgos.blogspot.com/上的 53. Edit Distance between strings

這道題目我們要設置兩個變量,i和j, E(i, j) 表示word1中以i 結尾的子串到表示word2中以j 結尾的子串的距離。

狀態轉移方程借助53. Edit Distance between strings上的這張圖片來說明:

 

LeetCode那道題的實現代碼,時間復雜度 O(n*n),空間復雜度O(n)

class Solution {
public:
    int minDistance(string word1, string word2) {
        if(word1.empty() && word2.empty()) return 0;
        int len1 = word1.length(), len2 = word2.length();
        int A[len2+1]; int pre;
        memset(A, 0, sizeof(A));
        for(int i = 0; i <= len1; ++i){
            for(int j = 0; j <= len2; ++j){
                int Min = INT_MAX;
                if(i > 0) Min = min(A[j]+1, Min);
                if(j > 0) Min = min(A[j-1]+1, Min);
                if(i > 0 && j > 0) Min = min(Min, pre+(word1[i-1] == word2[j-1] ? 0 : 1));
                if(i == 0 && j == 0) Min = 0;
                pre = A[j];
                A[j] = Min;
            }
        }
        return A[len2];
    }
};

 

 

后記

棋盤型二維動態規划典型的題目還有“尋找最長公共子串(substring)”,“尋找最長公共子序列(subsequence)”。

這些都可以給出時間復雜度 O(n*n),空間復雜度O(n)的解。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM