LeetCode 62/63/120/64 Unique PathsI/II Triangle/Min sum Path/Rectangle Area--DP

9218 단어 LeetCodearraydp
1: unique Path
제목:
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).
How many possible unique paths are there?
Above is a 3 x 7 grid. How many possible unique paths are there?
Note: m and n will be at most 100.
링크:https://leetcode.com/problems/unique-paths/
분석: 이 문제는 분명히 동적 기획 문제이다. F[m][n]을 사용했는데 그 중에서 F[i][j]는 (i, j) 위치에 있을 때의 최대 방안 수를 나타낸다. 그는 F[i+1][j]+F[i][j+1]와 같다. 
코드:
class Solution {
public:
    int uniquePaths(int m, int n) {
        int **path = new int*[m];
        for(int i = 0; i < m; i++){
            path[i] = new int[n];
            memset(path[i], 0, sizeof(int)*n);
        }
        for(int i = 0; i < m; i++)         //    
            path[i][n-1] = 1;
        for(int i = 0; i < n; i++)
            path[m-1][i] = 1;
        for(int i = m-2; i >=0; i--){
            for(int j = n-2; j >= 0; j--){
                path[i][j] = path[i+1][j] + path[i][j+1];   // DP  
            }
        }
        int pathes = path[0][0];
        for(int i = 0; i < m; i++)
            delete []path[i];
        delete []path;
        return pathes;
        
    }
};

2: Unique PathII
제목:
Follow up for "Unique Paths":
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.
링크:https://leetcode.com/problems/unique-paths-ii/
분석: 이 문제는 지난 문제에 장애물을 추가한 것으로 초기화에 어느 정도 영향을 미친다.
4
class Solution {
public:
    int uniquePathsWithObstacles(vector<vector<int> > &obstacleGrid) {
        int m = obstacleGrid.size();
        int n = obstacleGrid[0].size();
        if(obstacleGrid[m-1][n-1] || obstacleGrid[0][0]) return 0;
        int **path = new int*[m];
        for(int i = 0; i < m; i++){
            path[i] = new int[n];
            memset(path[i], 0, sizeof(int)*n);
        }
        path[m-1][n-1] = 1;
        
        for(int i = m-2; i >= 0; i--){         //                      
            if(obstacleGrid[i][n-1]) path[i][n-1] = 0;
            else path[i][n-1] = path[i+1][n-1];
            
        }
        for(int i = n-2; i >= 0; i--)
            if(obstacleGrid[m-1][i]) path[m-1][i] = 0;
            else path[m-1][i] = path[m-1][i+1];
            
            
        for(int i = m-2; i >=0; i--){
            for(int j = n-2; j >= 0; j--){
                if(obstacleGrid[i][j]) path[i][j] = 0;
                else path[i][j] = path[i+1][j] + path[i][j+1];   // DP  
            }
        }
        int pathes = path[0][0];
        for(int i = 0; i < m; i++)
            delete []path[i];
        delete []path;
        return pathes;
        
    }
};
3: Triangle
제목:
Given a triangle, find the minimum path sum from top to bottom. Each step you may move to adjacent numbers on the row below.
For example, given the following triangle
[
     [2],
    [3,4],
   [6,5,7],
  [4,1,8,3]
]

The minimum path sum from top to bottom is  11  (i.e., 2 + 3 + 5 + 1 = 11). 링크:https://leetcode.com/problems/triangle/
분석: F[i]로 위치가 i일 때의 최소 합을 나타낸다. 그는 =triangle[i]+min(F[i], F[i+1])의 전형적인 DP를 나타낸다.
코드:
class Solution {
public:
    int minimumTotal(vector<vector<int> > &triangle) {
        int lastCols = triangle[triangle.size()-1].size();
        int *f = new int[lastCols];
        for(int i = 0; i < lastCols; i++){
            f[i] = triangle[triangle.size()-1][i];         //    
        }
        for(int i = triangle.size()-2; i >=0; i--){
            for(int j = 0; j < triangle[i].size(); j++){
                f[j] = triangle[i][j] + min(f[j], f[j+1]);       //    
            }
        }
        int result = f[0];
        delete []f;
        return result;
        
    }
};

4: 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.
링크:https://leetcode.com/problems/minimum-path-sum/
코드:
class Solution {
public:
    int minPathSum(vector<vector<int> > &grid) {
        int m = grid.size();
        if(m == 0) return 0;
        int n = grid[0].size();
        if(n == 0) return 0;
        int **path = new int*[m];
        for(int i = 0; i < m; i++){
            path[i] = new int[n];
            memset(path[i], 0, sizeof(int)*n);
        }
        path[m-1][n-1] = grid[m-1][n-1];
        for(int i = m-2; i >= 0; i--){                  //         
            path[i][n-1] = path[i+1][n-1] + grid[i][n-1];
        }
        for(int i = n-2; i >= 0; i--){
            path[m-1][i] = path[m-1][i+1]+ grid[m-1][i];
        }
        for(int i = m-2; i >= 0; i--){              //       
            for(int j = n-2; j >= 0; j--)
                path[i][j] = grid[i][j] + min(path[i+1][j], path[i][j+1]);
        }
        int result = path[0][0];
        for(int i = 0; i < m; i++)
            delete []path[i];
        delete []path;
        return result;
        
        
    }
};

5: Rectangle Area
Given a 2D binary matrix filled with 0's and 1's, find the largest square containing all 1's and return its area.
For example, given the following matrix:
1 0 1 0 0
1 0 1 1 1
1 1 1 1 1
1 0 0 1 0

Return 4.
분석: 이 문제는 동적 기획 문제로 시간 복잡도는 틀림없이 O(M*N)이고 공간 복잡도는 O(min{M, N})로 낮출 수 있다.교체식은 square[i][j]=min(min(square[i][j+1],square[i+1][j]),square[i+1][j+1])이다.
코드:
class Solution {
public:
    int maximalSquare(vector<vector<char>>& matrix) {
        int m = matrix.size();
        if(m == 0) return 0;
        int n = matrix[0].size();
        int **square = new int*[m];
        for(int i = 0; i < m; i++){
            square[i] = new int[n];
            memset(square[i], 0, sizeof(int)*n);
        }
        int maxSquare = 0;
        for(int i = 0; i < m; i++){
            square[i][n-1] = matrix[i][n-1]-'0';
            maxSquare = max(maxSquare, square[i][n-1]);
        }
        for(int i = 0; i < n; i++){
            square[m-1][i] = matrix[m-1][i] - '0';
            maxSquare = max(maxSquare, square[m-1][i]);
        }
        
        for(int i = m-2; i >= 0; i--){
            for(int j = n-2; j >= 0; j--){
                if(matrix[i][j] == '1')
                    square[i][j] =min(min(square[i+1][j], square[i][j+1]), square[i+1][j+1])+1;
                else square[i][j] = 0;
                maxSquare = max(maxSquare, square[i][j]);
            }
        }
        return maxSquare*maxSquare;
    }
};

다음은 O (N) 공간의 복잡도 코드를 보여 줍니다.
class Solution {
public:
    int maximalSquare(vector<vector<char>>& matrix) {
        int m = matrix.size();
        if(m == 0) return 0;
        int n = matrix[0].size();
        int **square = new int*[2];
        for(int i = 0; i < 2; i++){
            square[i] = new int[n];
            memset(square[i], 0, sizeof(int)*n);
        }
        int maxSquare = 0;
       /* for(int i = 0; i < 2; i++){
            square[i][n-1] = matrix[i][n-1]-'0';
            maxSquare = max(maxSquare, square[i][n-1]);
        }*/
        for(int i = 0; i < n; i++){
            square[0][i] = matrix[m-1][i] - '0';
            maxSquare = max(maxSquare, square[0][i]);
        }
        
        for(int i = m-2; i >= 0; i--){
            square[1][n-1] = matrix[i][n-1]-'0';
            maxSquare = max(maxSquare, square[1][n-1]);
            int j = n-2;
            for(j = n-2; j >= 0; j--){
                if(matrix[i][j] == '1')
                    square[1][j] =min(min(square[0][j], square[1][j+1]), square[0][j+1])+1;  //  、 、        
                else square[1][j] = 0;
                maxSquare = max(maxSquare, square[1][j]);
                if(j+2 < n) square[0][j+2] =  square[1][j+2];
            }
            if(j+2 < n) square[0][j+2] = square[1][j+2];
            square[0][0] = square[1][0];
        }
        return maxSquare*maxSquare;
    }
};

좋은 웹페이지 즐겨찾기