力扣675. 为高尔夫比赛砍树

本文介绍了如何使用广度优先搜索(BFS)算法在森林图中寻找从起点到可以砍伐的树的最短路径,并计算总砍伐步数。通过优先级队列管理和路径判断,实现高效解决问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >



import java.util.*;

/**
 * @author xnl
 * @Description:
 * @date: 2022/5/23   22:13
 */
public class Solution {
    public static void main(String[] args) {
        Solution solution = new Solution();

    }

    // 上下左右四个方向
    int[][] dirs = {{-1,0}, {1, 0}, {0, -1}, {0, 1}};

    /**
     * 广度优先算法,
     *  1.先找到最短距离
     *  2.判断是否可以到达这个点
     * @param forest
     * @return
     */
    public int cutOffTree(List<List<Integer>> forest) {
        // 存放所有的可以砍得树
        List<int[]> trees = new ArrayList<int[]>();
        int row = forest.size();
        int col = forest.get(0).size();
        for (int i = 0; i < row; i++ ){
            for (int j = 0; j < col; j++){
                if (forest.get(i).get(j) > 1){
                    // 存放我们所有可以砍得树
                    trees.add(new int[]{i ,j});
                }
            }
        }
        Collections.sort(trees, (a, b) -> forest.get(a[0]).get(a[1]) - forest.get(b[0]).get(b[1]));

        int startX = 0, startY = 0, ans = 0;
        for (int i = 0; i < trees.size(); i++){
            int steps = bfs(forest, startX, startY, trees.get(i)[0], trees.get(i)[1]);
            if (steps == -1){
                return  -1;
            }
            startX = trees.get(i)[0];
            startY = trees.get(i)[1];
            ans += steps;
        }
        return ans;
    }

    private int bfs(List<List<Integer>> forest, int startX, int startY, int targetX, int targetY){
        // 匹配直接返回
        if (startX == targetX && startY == targetY){
            return 0;
        }

        int row = forest.size();
        int col = forest.get(0).size();
        int step = 0; // 需要走的步数
        boolean[][] visited = new boolean[row][col]; // 是否走过数组,深度优先遍历常用的数组
        visited[startX][startY] = true;
        Queue<int[]> stack = new ArrayDeque<>(); // 栈存放已经走过的数组,其实就相当于递归了
        stack.offer(new int[]{startX, startY});
        while (!stack.isEmpty()){
            step++;
            int size = stack.size();
            for (int i = 0; i < size; i++){
                int[] cell = stack.poll();
                int cx = cell[0], cy = cell[1]; // 临时存储一下值的东西,没有用处
                // 东西南北四个方向找,看看能不能匹配上
                for (int j = 0; j < 4; j++){
                    int nx = cx + dirs[j][0];
                    int ny = cy + dirs[j][1];
                    // 判断是否超过边界
                    if (nx >= 0 && nx < row && ny >= 0 && ny < col){
                        // 判断当前位置是否可以砍,是否已经砍过了
                        if (!visited[nx][ny] && forest.get(nx).get(ny) > 0){
                            // 如果符合要砍得数
                            if (nx == targetX && ny == targetY){
                                return step;
                            }
                            // 如果不符合,记录一下这个结果、
                            stack.offer(new int[]{nx, ny});
                            visited[nx][ny] = true;
                        }
                    }
                }
            }
        }
        return -1;
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值