引言
二維動態規划中最常見的是棋盤型二維動態規划。
即
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)的解。