zoukankan      html  css  js  c++  java
  • 有些障碍的 unique path

    我第一时间想到的方案是化归而不是规划,毕竟之前的问题类似,所以就有了这个版本:

    int uniquePathsWithObstacles(vector<vector<int>>& obstacleGrid) {
        if (obstacleGrid.empty()){
            return 0;
        }
        const int begin = obstacleGrid.front().front();
        if (begin == 1){
            return 0;
        }
        const size_t m = obstacleGrid.size();
        const size_t n = obstacleGrid.front().size();
        
        vector<vector<int>> record((m), vector<int>(n));
        function<int(size_t, size_t)> getPathsNum;
        getPathsNum = [&](int a, int b)
        {
            if (obstacleGrid[a][b] == 1){
                return 0;
            }
            
            if (a == 0 && b == 0){
                return 1;
            }
            int&& result = 0;
            if (a == 0){
                result = getPathsNum(0, b - 1);
                record[a][b] = result;
                return result;
            }
            if (b == 0){
                result = getPathsNum(a - 1, 0);
                record[a][b] = result;
                return result;
            }
            const int paths_num = record[a][b];
            if (paths_num != 0){
                return paths_num;
            }
            result = getPathsNum(a - 1, b) + getPathsNum(a, b - 1);
            record[a][b] = result;
            return result;
        };
        return getPathsNum(m - 1, n - 1);
    }

    感觉:嗯嗯,可以可以。一测时间, 92 ms。尼玛用 ruby 的都比我速度快,这玩毛。

    后来发现我又陷入 DP 就是递归的思维定势里了,f(m, n) = f(m - 1, n) + f(m, n -1) 这个式子固然可以反着推,但正着填充不是更好?这才发现上面的版本根本不是用的动态规划的思想。

    真正 DP 的思想是填充。当然填充也很简单大概意思就是 result[m, n] = result[m - 1, n] + result[m, n - 1]。这才是动规的思想好不拉!

    能更省空间吗?我发现其实每一行的结果只依赖上一行,再往上的对它并没有直接影响。那还存储它们作甚?所以只需要一行数据的空间,然后逐行扫描。

    int uniquePathsWithObstacles(vector<vector<int> > &obstacleGrid) {
        if (obstacleGrid.empty() || obstacleGrid[0][0] == 1 ||
            obstacleGrid.back().back() == 1){
            return 0;
        }
        const size_t row_length = obstacleGrid[0].size();
        vector<int> row(row_length);
        auto const& first_row = obstacleGrid[0];
        bool is_blocked = false;
        for (size_t i = 0; i != row_length; ++i){
            if (is_blocked || first_row[i] == 1){
                row[i] = 0;
                is_blocked = true;
            }else{
                row[i] = 1;
            }
        }
        for (size_t i = 1; i != obstacleGrid.size(); ++i){
            for (size_t j = 0; j != row_length; ++j){
                if (obstacleGrid[i][j] == 1){
                    row[j] = 0;
                }
                else if (j > 0){
                    row[j] = row[j] + row[j - 1];
                }
            }
        }
        return row.back();
    }
  • 相关阅读:
    数据绑定
    快速上手小程序云开发
    微信小程序敏捷开发实战
    测试驱动开发实践4————testSave之新增文档分类
    测试驱动开发实践3————从testList开始
    测试驱动开发实践2————测试驱动开发之前
    测试驱动开发实践1————项目代码生成
    构建微服务开发环境8————Hello 微服务
    构建微服务开发环境7————使用Github管理项目代码的版本
    构建微服务开发环境6————利用npm安装前端框架
  • 原文地址:https://www.cnblogs.com/wuOverflow/p/5045756.html
Copyright © 2011-2022 走看看