• 675. Cut Off Trees for Golf Event


    // Potential improvements:
    // 1. we can use vector<int> { h, x, y } to replace Element, sorting vector is to compare elements one by one.
    // 2. use 2-d bool vector<vector<bool>> to replace unordered_set.
    
    class Element {
    public:
        int x, y, h;
        Element(int x, int y, int h) {
            this->x = x;
            this->y = y;
            this->h = h;
        }
    };
    class Solution {
    public:
        int m;
        int n;
        int cutOffTree(vector<vector<int>>& forest) {
            m = forest.size();  if (m == 0) return 0;
            n = forest[0].size();   if (n == 0) return 0;
            vector<Element> v;
            for (int i = 0; i < m; i++)
                for (int j = 0; j < n; j++)
                    if (forest[i][j] > 1)
                        v.emplace_back(i, j, forest[i][j]);
            auto comp = [](const Element& a, const Element& b) { return a.h < b.h; };
            v.emplace_back(0, 0, 0);
            sort(v.begin(), v.end(), comp);
            
            int res = 0;
            for (int i = 0; i < v.size()  - 1; i++) {
                int t = helper(forest, v[i], v[i+1]);
                if (t < 0)  return t;
                res += t;
            }
            return res;
        }
        int helper(vector<vector<int>>& forest, const Element& a, const Element& b) {
            const int dirs[] = { -1, 0, 1, 0, -1 };
            // (x,y) is small enough, so x*n+y won't overflow. otherwise we have to use long,
            // and be careful x*n+y will overflow, we may use (long)x*n+y instead.
            unordered_set<int> s;   
            queue<pair<int,int>> q;
            q.push({a.x, a.y});
            s.insert(a.x * n + a.y);
            int lv = 0;
            while (!q.empty()) {
                int qsz = q.size();
                for (int i = 0; i < qsz; i++) {
                    auto cur = q.front();
                    q.pop();
                    if (cur.first == b.x && cur.second == b.y)
                        return lv;
                    for (int i = 0; i < 4; i++) {
                        int nx = cur.first + dirs[i];
                        int ny = cur.second + dirs[i+1];
                        pair<int,int> np = {nx,ny};
                        if (nx >= 0 && nx < m && ny >= 0 && ny < n && 
                            forest[nx][ny] > 0 &&
                            s.find(nx * n + ny) == s.end()) {
                            q.push(np);
                            s.insert(nx * n + ny);
                        }
                    }
                }
                lv++;
            }
            return -1;
        }
    };

     huge perf improve from 1000+ ms to 300 ms: 

    use 2-d bool vector<vector<bool>> to replace unordered_set
    class Element {
    public:
        int x, y, h;
        Element(int x, int y, int h) {
            this->x = x;
            this->y = y;
            this->h = h;
        }
    };
    class Solution {
    public:
        int m;
        int n;
        int cutOffTree(vector<vector<int>>& forest) {
            m = forest.size();  if (m == 0) return 0;
            n = forest[0].size();   if (n == 0) return 0;
            vector<Element> v;
            for (int i = 0; i < m; i++)
                for (int j = 0; j < n; j++)
                    if (forest[i][j] > 1)
                        v.emplace_back(i, j, forest[i][j]);
            auto comp = [](const Element& a, const Element& b) { return a.h < b.h; };
            v.emplace_back(0, 0, 0);
            sort(v.begin(), v.end(), comp);
            
            int res = 0;
            for (int i = 0; i < v.size()  - 1; i++) {
                int t = helper(forest, v[i], v[i+1]);
                if (t < 0)  return t;
                res += t;
            }
            return res;
        }
        int helper(vector<vector<int>>& forest, const Element& a, const Element& b) {
            const int dirs[] = { -1, 0, 1, 0, -1 };
            // (x,y) is small enough, so x*n+y won't overflow. otherwise we have to use long,
            // and be careful x*n+y will overflow, we may use (long)x*n+y instead.
            vector<vector<bool>> s(m, vector<bool>(n));
            queue<pair<int,int>> q;
            q.emplace(a.x, a.y);
            s[a.x][a.y] = true;
            int lv = 0;
            while (!q.empty()) {
                int qsz = q.size();
                for (int i = 0; i < qsz; i++) {
                    auto cur = q.front();
                    q.pop();
                    if (cur.first == b.x && cur.second == b.y)
                        return lv;
                    for (int i = 0; i < 4; i++) {
                        int nx = cur.first + dirs[i];
                        int ny = cur.second + dirs[i+1];
                        pair<int,int> np = {nx,ny};
                        if (nx >= 0 && nx < m && ny >= 0 && ny < n && 
                            forest[nx][ny] > 0 &&
                            !s[nx][ny]) {
                            q.push(np);
                            s[nx][ny] = true;
                        }
                    }
                }
                lv++;
            }
            return -1;
        }
    };
  • 相关阅读:
    Eclipse 安装配置指南
    CentOS下安装Git
    MySQL5.5在Windows下的安装
    NSInvocation调用
    动态调用
    模拟静态变量及静态类继承
    respondsToSelector判断是否实现了某方法
    JAVA闭包
    IMP获取函数指针
    [链表] 对链表与文件的结合使用的一点看法
  • 原文地址:https://www.cnblogs.com/JTechRoad/p/10041759.html
Copyright © 2020-2023  润新知