​LeetCode解法汇总2477. 到达首都的最少油耗

 目录链接:

力扣编程题-解法汇总_分享+记录-CSDN博客

GitHub同步刷题项目:

https://github.com/September26/java-algorithms

原题链接:力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台


描述:

给你一棵 n 个节点的树(一个无向、连通、无环图),每个节点表示一个城市,编号从 0 到 n - 1 ,且恰好有 n - 1 条路。0 是首都。给你一个二维整数数组 roads ,其中 roads[i] = [ai, bi] ,表示城市 ai 和 bi 之间有一条 双向路 。

每个城市里有一个代表,他们都要去首都参加一个会议。

每座城市里有一辆车。给你一个整数 seats 表示每辆车里面座位的数目。

城市里的代表可以选择乘坐所在城市的车,或者乘坐其他城市的车。相邻城市之间一辆车的油耗是一升汽油。

请你返回到达首都最少需要多少升汽油。

示例 1:

输入:roads = [[0,1],[0,2],[0,3]], seats = 5
输出:3
解释:
- 代表 1 直接到达首都,消耗 1 升汽油。
- 代表 2 直接到达首都,消耗 1 升汽油。
- 代表 3 直接到达首都,消耗 1 升汽油。
最少消耗 3 升汽油。

示例 2:

输入:roads = [[3,1],[3,2],[1,0],[0,4],[0,5],[4,6]], seats = 2
输出:7
解释:
- 代表 2 到达城市 3 ,消耗 1 升汽油。
- 代表 2 和代表 3 一起到达城市 1 ,消耗 1 升汽油。
- 代表 2 和代表 3 一起到达首都,消耗 1 升汽油。
- 代表 1 直接到达首都,消耗 1 升汽油。
- 代表 5 直接到达首都,消耗 1 升汽油。
- 代表 6 到达城市 4 ,消耗 1 升汽油。
- 代表 4 和代表 6 一起到达首都,消耗 1 升汽油。
最少消耗 7 升汽油。

示例 3:

输入:roads = [], seats = 1
输出:0
解释:没有代表需要从别的城市到达首都。

提示:

  • 1 <= n <= 105
  • roads.length == n - 1
  • roads[i].length == 2
  • 0 <= ai, bi < n
  • ai != bi
  • roads 表示一棵合法的树。
  • 1 <= seats <= 105

解题思路:

首先广度搜索,找到分别走1步,2步,N步可以达到的城市。

然后从走N步可到达的城市开始,N步计算出需要多少油耗。

然后这个城市要达到的城市对应的人数+1,计算N-1步可以到达的。

 

代码:

class Solution {
    //达到key的节点集合
    Map<Integer, List<Integer>> map = new HashMap<>();
    Node[] nodes = new Node[100000];
    List<List<Node>> stepList = new ArrayList<>();

    public long minimumFuelCost(int[][] roads, int seats) {
        //广度遍历
        breadthSearch(roads);
        long sum = 0L;
        for (int i = stepList.size() - 1; i >= 0; i--) {
            System.out.println("sum:" + sum);
            for (Node itemNode : stepList.get(i)) {
                int to = itemNode.to;
                Node toNode = nodes[to];
                toNode.num += itemNode.num;
                sum += itemNode.num / seats;
                if (itemNode.num % seats != 0) {
                    sum++;
                }
            }
            System.out.println("sum:" + sum);
        }
        return sum;
    }

    private void breadthSearch(int[][] roads) {
        for (int[] road : roads) {
            int i1 = road[0];
            int i2 = road[1];
            addList(i1, i2);
            addList(i2, i1);
        }
        Node rootNode = new Node(0);
        nodes[0] = rootNode;
        List<Node> list = new ArrayList<>();
        list.add(rootNode);
        buildStepMap(list, 0);
    }

    private void addList(int to, int from) {
        List<Integer> integers = map.get(to);
        if (integers == null) {
            integers = new ArrayList<>();
            map.put(to, integers);
        }
        integers.add(from);
    }


    private void buildStepMap(List<Node> nodeList, int step) {
        List<Node> newNodeList = new ArrayList<>();
        step++;
        for (Node node : nodeList) {
            List<Integer> integers = map.get(node.pos);
            if (integers == null) {
                continue;
            }
            for (int i : integers) {
                if (nodes[i] != null) {
                    continue;
                }
                Node newNode = new Node(i);
                newNode.to = node.pos;
                newNode.step = step;
                nodes[i] = newNode;
                newNodeList.add(newNode);
            }
        }
        if (newNodeList.size() == 0) {
            return;
        }
        stepList.add(newNodeList);
        buildStepMap(newNodeList, step);
    }


    static class Node {
        int pos = 0;
        int to = 0;
        long num = 1;
        int step = 0;

        Node(int pos) {
            this.pos = pos;
        }
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

失落夏天

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值