✅ C++ || Recursion ➡️ Memoization ➡️ Tabulation ➡️ Space Optimization || Striver
Recursion:\n\nclass Solution {\npublic:\n    int f(int m, int n, vector<vector<int>>& grid){\n        if(m<0 or n<0 or grid[m][n]==1) return 0;\n\t\tif(m==0 && 
**Recursion:**\n```\nclass Solution {\npublic:\n    int f(int m, int n, vector<vector<int>>& grid){\n        if(m<0 or n<0 or grid[m][n]==1) return 0;\n\t\tif(m==0 && n==0) return 1;\n        int left=f(m,n-1,grid);\n        int up=f(m-1,n,grid);\n        return left+up;\n    }\n    int uniquePathsWithObstacles(vector<vector<int>>& grid) {\n        int m=grid.size(), n=grid[0].size();\n        return f(m-1,n-1,grid);\n    }\n};\n```\n\n**memoization:**\n```\nclass Solution {\npublic:\n    int f(int m, int n, vector<vector<int>>& grid, vector<vector<int>>& dp){\n        if(m<0 or n<0 or grid[m][n]==1) return 0;\n        if(m==0 && n==0) return 1;\n        if(dp[m][n]!=-1) return dp[m][n];\n        int left=f(m,n-1,grid,dp);\n        int up=f(m-1,n,grid,dp);\n        return dp[m][n]=left+up;\n    }\n    int uniquePathsWithObstacles(vector<vector<int>>& grid) {\n        int m=grid.size(), n=grid[0].size();\n        vector<vector<int>> dp(m, vector<int>(n,-1));\n        return f(m-1,n-1,grid,dp); \n    }\n};\n```\n\n**tabulation:**\n```\nclass Solution {\npublic:\n    int f(int m, int n, vector<vector<int>>& grid){\n        vector<vector<int>> dp(m, vector<int>(n));\n        for(int i=0;i<m;i++){\n            for(int j=0;j<n;j++){\n                if(grid[i][j]==1) dp[i][j]=0;\n                else if(i==0 && j==0) dp[i][j]=1;\n                else{\n                    int left=0,up=0;\n                    if(j-1>=0) left=dp[i][j-1];\n                    if(i-1>=0) up=dp[i-1][j];\n                    dp[i][j]=left+up;\n                }\n            }\n        }\n        return dp[m-1][n-1];\n    }\n\t\tint uniquePathsWithObstacles(vector<vector<int>>& grid) {\n        return f(m,n,grid); \n    }\n};\n```\n**space optimization:**\n```\nclass Solution {\npublic:\n    int f(int m, int n, vector<vector<int>>& grid){\n        vector<int> dp(n);\n        for(int i=0;i<m;i++){\n            for(int j=0;j<n;j++){\n                if(grid[i][j]==1) dp[j]=0;\n                else if(i==0 && j==0) dp[j]=1;\n                else{\n                    int left=0,up=0;\n                    if(j-1>=0) left=dp[j-1];\n                    if(i-1>=0) up=dp[j];\n                    dp[j]=left+up;\n                }\n            }\n        }\n        return dp[n-1];\n    }\n    int uniquePathsWithObstacles(vector<vector<int>>& grid) {\n        int m=grid.size(), n=grid[0].size();\n        return f(m,n,grid);\n    }\n};\n```
['Dynamic Programming', 'Recursion', 'Memoization', 'C', 'C++']