Loading

Leetcode1584. 连接所有点的最小费用

1584. 连接所有点的最小费用

Difficulty: 中等

给你一个points 数组,表示 2D 平面上的一些点,其中 points[i] = [x<sub style="display: inline;">i</sub>, y<sub style="display: inline;">i</sub>] 。

连接点 [x<sub style="display: inline;">i</sub>, y<sub style="display: inline;">i</sub>] 和点 [x<sub style="display: inline;">j</sub>, y<sub style="display: inline;">j</sub>] 的费用为它们之间的 曼哈顿距离 :|x<sub style="display: inline;">i</sub> - x<sub style="display: inline;">j</sub>| + |y<sub style="display: inline;">i</sub> - y<sub style="display: inline;">j</sub>| ,其中 |val| 表示 val 的绝对值。

请你返回将所有点连接的最小总费用。只有任意两点之间 有且仅有 一条简单路径时,才认为所有点都已连接。

示例 1:

输入:points = [[0,0],[2,2],[3,10],[5,2],[7,0]]
输出:20
解释:

我们可以按照上图所示连接所有点得到最小总费用,总费用为 20 。
注意到任意两个点之间只有唯一一条路径互相到达。

示例 2:

输入:points = [[3,12],[-2,5],[-4,1]]
输出:18

示例 3:

输入:points = [[0,0],[1,1],[1,0],[-1,1]]
输出:4

示例 4:

输入:points = [[-1000000,-1000000],[1000000,1000000]]
输出:4000000

示例 5:

输入:points = [[0,0]]
输出:0

提示:

  • 1 <= points.length <= 1000
  • -10<sup>6</sup> <= x<sub style="display: inline;">i</sub>, y<sub style="display: inline;">i</sub> <= 10<sup>6</sup>
  • 所有点 (x<sub style="display: inline;">i</sub>, y<sub style="display: inline;">i</sub>) 两两不同。

Solution

思路:题意就是寻找最小代价生成树,使用prim算法

Language: java

/**
*      查看了下prim最小代价生成树算法,对之前的代码进行改进
*/
class Solution {
    public int minCostConnectPoints(int[][] points) {
        int cost = 0;
        int[][] mg = new int[points.length][points.length];      //将points的点数据转化为边数据
        for(int i=0; i<points.length; i++){
            for(int j=i+1; j<points.length; j++){
                mg[i][j] = Math.abs(points[i][0]-points[j][0])+Math.abs(points[i][1]-points[j][1]);
                mg[j][i] = mg[i][j];
            }
        }
        int[] lowCost = new int[points.length];      //记录到树结点的最小代价
        for(int i=1; i<points.length; i++){
            lowCost[i] = mg[0][i];      //初始化,默认使用第一个point作为树的最开始结点
        }
        for(int i=1; i<points.length; i++){
            long minCost = Long.MAX_VALUE;
            int minIdx = 0;
            for(int j=0; j<points.length; j++){      //遍历所有结点,寻找最小代价
                if(lowCost[j] != 0 && lowCost[j] < minCost){
                    minCost = lowCost[j];
                    minIdx = j;
                }
            }
            cost += minCost;
            for(int j=0; j<points.length; j++){      //更新其他点到树结点的最小代价
                if(lowCost[j] != 0 && mg[minIdx][j] < lowCost[j]){
                    lowCost[j] = mg[minIdx][j];
                }
            }
        }
        return cost;
    }
}

执行用时:38 ms, 在所有 Java 提交中击败了88.42%的用户
内存消耗:42.8 MB, 在所有 Java 提交中击败了84.17%的用户

/**
*      使用prim算法,超时了
*      ps:自己按照prim算法思想进行实现,所以超时了
*/
class Solution {
    public int minCostConnectPoints(int[][] points) {
        int cost = 0;
        List<Integer> treeNode = new ArrayList<>();
        Set<Integer> set = new HashSet<>();
        treeNode.add(0);set.add(0);
        while(treeNode.size() != points.length){
            long min = Long.MAX_VALUE;
            int idx = 0;
            for(int i=0; i<treeNode.size(); i++){
                int x = treeNode.get(i);
                for(int j=0; j<points.length; j++){
                    if(set.contains(j)) continue;
                    int len = Math.abs(points[x][0] - points[j][0])+Math.abs(points[x][1] - points[j][1]);
                    if(len < min){
                        min = len;
                        idx = j;
                    }
                }
            }
            cost += min;
            set.add(idx);
            treeNode.add(idx);
        }
        return cost;
    }
}
posted @ 2021-01-20 00:06  yoyuLiu  阅读(75)  评论(0编辑  收藏  举报