九章算法 - 一、坐标型动态规划 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> &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> f(m,vector(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& 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 > &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> &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;
    }
};

 

你可能感兴趣的:(LeetCode)