675. Cut Off Trees for Golf Event


/*
Since we have to cut trees in order of their height, we first put trees (int[] {row, col, height}) into a priority queue and sort by height.
Poll each tree from the queue and use BFS to find out steps needed.
The worst case time complexity could be O(m^2 * n^2) (m = number of rows, n = number of columns) since there are m * n trees and for each BFS worst case time complexity is O(m * n) too.




class Solution {
    static int[][] dir = {{0,1}, {0, -1}, {1, 0}, {-1, 0}};


    public int cutOffTree(List<List<Integer>> forest) {
        if (forest == null || forest.size() == 0) return 0;
        int m = forest.size(), n = forest.get(0).size();


        PriorityQueue<int[]> pq = new PriorityQueue<>((a, b) -> a[2] - b[2]);


        for (int i = 0; i < m; i++) {
            for (int j = 0; j < n; j++) {
                if (forest.get(i).get(j) > 1) {
                    pq.add(new int[] {i, j, forest.get(i).get(j)});
                }
            }
        }


        int[] start = new int[2];
        int sum = 0;
        while (!pq.isEmpty()) {
            int[] tree = pq.poll();
            int step = minStep(forest, start, tree, m, n);


            if (step < 0) return -1;
            sum += step;


            start[0] = tree[0];
            start[1] = tree[1];
        }


        return sum;
    }


    private int minStep(List<List<Integer>> forest, int[] start, int[] tree, int m, int n) {
        int step = 0;
        boolean[][] visited = new boolean[m][n];
        Queue<int[]> queue = new LinkedList<>();
        queue.add(start);
        visited[start[0]][start[1]] = true;


        while (!queue.isEmpty()) {
            int size = queue.size();
            for (int i = 0; i < size; i++) {
                int[] curr = queue.poll();
                if (curr[0] == tree[0] && curr[1] == tree[1]) return step;


                for (int[] d : dir) {
                    int nr = curr[0] + d[0];
                    int nc = curr[1] + d[1];
                    if (nr < 0 || nr >= m || nc < 0 || nc >= n 
                        || forest.get(nr).get(nc) == 0 || visited[nr][nc]) continue;
                    queue.add(new int[] {nr, nc});
                    visited[nr][nc] = true;
                }
            }
            step++;
        }


        return -1;
    }
}


*/
/*
1. build priority queue by the weight of the trees
2. start from 0,0 to the lowest tree, and the compute the minSteps of this tree.从最小的树开始。
3. change the start to the lowest tree and cut the second lowest tree. 从次小的开始。
4. BFS 找出从当前位置到目标树的最短距离。
*/
typedef struct position position_t;
struct position
{
    int row;
    int col;
    int height;
    position(int r, int c, int h):row(r),col(c),height(h){};
};
auto tree_compare = [](position_t firstTree, position_t secondTree){
    return firstTree.height > secondTree.height;
};
class Solution {
private:
    vector<vector<int>> directs{{0,1},{1,0},{-1,0},{0,-1}};
    int minSteps(position_t& start, position_t& end, vector<vector<int>>& forest)
    {
        if(0 == start.height) return -1;
        int rows = forest.size();
        int cols = forest[0].size();
        vector<vector<bool>> seen(rows,vector<bool>(cols,false));
        seen[start.row][start.col] = true;
        queue<position_t> q;
        q.push(start);
        int step = 0;
        while(!q.empty())
        {
           int sizeOneLayer = q.size();
           for(int i = 0; i<sizeOneLayer;i++)
           {
                position_t curPos = q.front(); q.pop();
                if(curPos.row == end.row && curPos.col == end.col) return step;
                for(auto direct:directs)
                {
                    //int newRow = start.row + direct[0];   // should be curPos, not start......!!!!!
int newRow = curPos.row + direct[0];
//int newCol = start.col + direct[1]; 
                    int newCol = curPos.col + direct[1];    // should be curPos, not start......!!!!!
                    if(newRow <0    || newRow >=rows 
                                    || newCol <0 || newCol >=cols
                                    //|| forest[newRow][newCol]<1
                                    || forest[newRow][newCol]==0
                                    || seen[newRow][newCol]
                    ) continue;
                    else
                    {
                            q.push(position_t(newRow,newCol,forest[newRow][newCol]));
                            seen[newRow][newCol] = true;
                    }
                }
                //++step;
           }
           ++step;
        }
        return -1;
        //...
    }
public:
    int cutOffTree(vector<vector<int>>& forest) {
        if(forest.size() == 0) return 0;        
        // build priority queue by the weight of the trees
        priority_queue<position_t,vector<position_t>,decltype(tree_compare)> pq(tree_compare);
        int rows = forest.size();
        int cols = forest[0].size();
        for(int i = 0; i<rows;i++)
            for(int j = 0;j<cols;j++)
            {
                if(forest[i][j] > 1) pq.push(position_t(i,j,forest[i][j]));
            };
        int ans = 0;
        position_t start(0,0,forest[0][0]);
        // start from 0,0 to the lowest tree, and the compute the minSteps of this tree. 
        while(!pq.empty())
        {
            position_t target = pq.top(); pq.pop();
            int step = 0;
            step = minSteps(start,target,forest);
            if(step == -1) return -1;
            ans += step;
            // change the start to the lowest tree and cut the second lowest tree
            start = target;
        }
        
        return ans;
    }
};

void main()
{
// [[54581641,64080174,24346381,69107959],[86374198,61363882,68783324,79706116],[668150,92178815,89819108,94701471],[83920491,22724204,46281641,47531096],[89078499,18904913,25462145,60813308]]
//vector<vector<int>> forest{ {1,2,3},{0,0,4},{7,6,5} };
vector<vector<int>> forest{ { 54581641,64080174,24346381,69107959 },{ 86374198,61363882,68783324,79706116 },{ 668150,92178815,89819108,94701471 },{ 83920491,22724204,46281641,47531096 },{ 89078499,18904913,25462145,60813308 } };
Solution().cutOffTree(forest);
}

猜你喜欢

转载自blog.csdn.net/bjzhaoxiao/article/details/80276870
cut