九章算法 - 一、座標型動態規劃 115. 397. 110. 553.

115.Unique Path II

"不同的路徑" 的跟進問題:

現在考慮網格中有障礙物,那樣將會有多少條不同的路徑?

網格中的障礙和空位置分別用 1 和 0 來表示。

提示:注意初始化與前面不同,只能初始化第一個點。遍歷f[m][n],一旦有障礙就設置爲0,有左面或前面就+=。

答案:

class Solution {
public:
    /**
     * @param obstacleGrid: A list of lists of integers
     * @return: An integer
     */
    int uniquePathsWithObstacles(vector<vector<int>> &obstacleGrid) {
        // write your code here
        int m = obstacleGrid.size();
        if(m == 0){
            return 0;
        }
        int n = obstacleGrid[0].size();
        if(n == 0){
            return 0;
        }
        vector<vector<int>> f(m,vector<int>(n));
        int i,j;
        for(i = 0; i < m; ++i){
            for(j = 0; j < n; ++j){
                if(obstacleGrid[i][j] == 1){
                    f[i][j] = 0;
                }
                else{
                    if(i == 0 && j == 0){
                        f[i][j] = 1;
                    }
                    else{
                        f[i][j] = 0;
                        if(i - 1 >= 0){
                            f[i][j] += f[i-1][j];
                        }
                        if(j - 1 >= 0){
                            f[i][j] += f[i][j - 1];
                        }
                    }
                    
                }
                 
            }
        }
        return f[m - 1][n - 1];
    }
};

397. Longest Increasing Continuous Subsequence

給定一個整數數組(下標從 0 到 n-1, n 表示整個數組的規模),請找出該數組中的最長上升連續子序列。(最長上升連續子序列可以定義爲從右到左或從左到右的序列。)

提示:如果當前位置的數字比前一個大,那麼臨時最大值+1,一旦不比前一個數字大,那麼臨時最大值與最大值做比較,把臨時最大值設置爲1。此題目示例單調遞減也算。此題目可以壓縮空間到f[2]。

答案:

class Solution {
public:
    /**
     * @param A an array of Integer
     * @return  an integer
     */
    int longestIncreasingContinuousSubsequence(vector<int>& A) {
        // Write your code here
        int max = 1, s = 1, l = 1;
        int len = A.size();
        if (len == 0)
            return 0;
        for (int i = 1; i < len; ++i) {
            if (A[i] > A[i-1])
                s += 1;
            else {
                if (s > max) max = s;
                s = 1;
            } 
            
            if (A[i] < A[i-1])
                l += 1;
            else {
                if (l > max) max = l;
                l = 1;
            } 
        }
        if (s > max) max = s;
        if (l > max) max = l;
        return max;
    }
};

110. Minimum Path Sum

給定一個只含非負整數的m*n網格,找到一條從左上角到右下角的可以使數字和最小的路徑。

提示:Dp[i][j] 存儲從(0, 0) 到(i, j)的最短路徑。
           Dp[i][j] = min(Dp[i-1][j]), Dp[i][j-1]) + grid[i][j];

答案:

class Solution {
public:
    /**
     * @param grid: a list of lists of integers.
     * @return: An integer, minimizes the sum of all numbers along its path
     */
    int minPathSum(vector<vector<int> > &grid) {
        // write your code here
        int f[1000][1000];
        if (grid.size() == 0 || grid[0].size() == 0)
            return 0;
        f[0][0] = grid[0][0];
        for(int i = 1; i < grid.size(); i++)
            f[i][0] = f[i-1][0] + grid[i][0];
        for(int i = 1; i < grid[0].size(); i++)
            f[0][i] = f[0][i-1] + grid[0][i];
        for(int i = 1; i < grid.size(); i++)
            for(int j = 1; j < grid[0].size(); j++)
                f[i][j] = min(f[i-1][j], f[i][j-1]) + grid[i][j];
                
        return f[grid.size()-1][grid[0].size()-1];
    }
};

553. Bomb Enemy

給定一個二維矩陣, 每一個格子可能是一堵牆 W,或者 一個敵人 E 或者空 0 (數字 '0'), 返回你可以用一個炸彈殺死的最大敵人數. 炸彈會殺死所有在同一行和同一列沒有牆阻隔的敵人。 由於牆比較堅固,所以牆不會被摧毀.

提示:分爲四個方向,分別計算每個點在指定方向能炸到的敵人數量,有敵人初始爲1+前一個點但不進入最大值計算,有牆直接            爲0。   一定要注意,行與列前後別搞反了!!!

答案:

class Solution {
public:
    /**
     * @param grid: Given a 2D grid, each cell is either 'W', 'E' or '0'
     * @return: an integer, the maximum enemies you can kill using one bomb
     */
    int maxKilledEnemies(vector<vector<char>> &grid) {
        // write your code here
        if(grid.size() == 0 || grid[0].size() == 0){
            return 0;
        }
        
        int m = grid.size();
        int n = grid[0].size();
        
        int left[m][n], right[m][n], up[m][n], down[m][n];
       // memset(left, 0, sizeof(left));
       // memset(right, 0, sizeof(right));
       // memset(up, 0, sizeof(up));
//memset(down, 0, sizeof(down));
        int i, j, t;
        
        for(i = 0; i < m; ++i){
            for(j = 0; j < n; ++j){
                up[i][j] = 0;
                if(grid[i][j] != 'W'){
                    if(grid[i][j] == 'E'){
                        up[i][j] = 1;
                    }
                    if(i - 1 >= 0){
                        up[i][j] += up[i-1][j];
                    }
                }
            }
        }
        
        for(i = m - 1; i >= 0; --i){
            for(j = 0; j < n; ++j){
                down[i][j] = 0;
                if(grid[i][j] != 'W'){
                    if(grid[i][j] == 'E'){
                        down[i][j] = 1;
                    }
                    if(i + 1 < m){
                        down[i][j] += down[i+1][j];
                    }
                }
            }
        }
        
        for(i = 0; i < m; ++i){
            for(j = 0; j < n; ++j){
                left[i][j] = 0;
                if(grid[i][j] != 'W'){
                    if(grid[i][j] == 'E'){
                        left[i][j] = 1;
                    }
                    if(j - 1 >= 0){
                        left[i][j] += left[i][j-1];
                    }
                }
            }
        }
        
        for(i = 0; i < m; ++i){
            for(j = n - 1; j >= 0; --j){
                right[i][j] = 0;
                if(grid[i][j] != 'W'){
                    if(grid[i][j] == 'E'){
                        right[i][j] = 1;
                    }
                    if(j + 1 < n){
                        right[i][j] += right[i][j+1];
                    }
                }
            }
        }
        int res = 0;
        for (i = 0; i < m; ++i) {
            for (j = 0; j < n; ++j) {
                if (grid[i][j] == '0') {
                    t = up[i][j] + down[i][j] + left[i][j] + right[i][j];
                    if (t > res) {
                        res = t;
                    }
                }
            }
        }
        
        return res;
    }
};

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章