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;
}
}