C++ O(MN) time, O(1) space (use obstacleGrid)
use obstacleGrid to save result\n\n    int uniquePathsWithObstacles(vector>& obstacleGrid) {\n        int h = obstacleGrid.size();\n        if(h == 0) return 0;
use obstacleGrid to save result\n\n    int uniquePathsWithObstacles(vector<vector<int>>& obstacleGrid) {\n        int h = obstacleGrid.size();\n        if(h == 0) return 0;\n        int w = obstacleGrid[0].size();\n        if(w == 0) return 0;\n        if(obstacleGrid[0][0]) return 0;\n        \n        // first cell has 1 path\n        obstacleGrid[0][0] = 1;\n        \n        // first row all are '1' until obstacle (from left only)\n        for(int i=1; i<w; i++){\n            obstacleGrid[0][i] = obstacleGrid[0][i] ? 0 : obstacleGrid[0][i-1];\n        }\n\n        for(int j=1; j<h; j++){\n            // first column is like first row (from top only)\n            obstacleGrid[j][0] = obstacleGrid[j][0] ? 0 : obstacleGrid[j-1][0];\n            \n            // others are up+left\n            for(int i=1; i<w; i++){\n                obstacleGrid[j][i] = obstacleGrid[j][i] ? 0 : obstacleGrid[j-1][i] + obstacleGrid[j][i-1];\n            }\n        }\n        \n        return obstacleGrid[h-1][w-1];\n    }
[]