zoukankan      html  css  js  c++  java
  • Leetcode 1584连接所有点的最小费用

    题目定义:

    给你一个points 数组,表示 2D 平面上的一些点,其中 points[i] = [xi, yi] 。
    
    连接点 [xi, yi] 和点 [xj, yj] 的费用为它们之间的 
          曼哈顿距离 :|xi - xj| + |yi - yj| ,其中 |val| 表示 val 的绝对值。
    
    请你返回将所有点连接的最小总费用。只有任意两点之间 有且仅有 一条简单路径时,才认为所有点都已连接。
    
    示例 1:
    
    输入:points = [[0,0],[2,2],[3,10],[5,2],[7,0]]
    输出:20
    

    img

    我们可以按照上图所示连接所有点得到最小总费用,总费用为 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
    

    方式一(kruskal):

    class Solution {
        public int minCostConnectPoints(int[][] points) {
            int length = points.length,ans = 0,num = 0;
            List<Edge> edgs = new ArrayList<>(); 
            UnionFind unionFind = new UnionFind(length);
            for(int i = 0; i < length; i++)
                for(int j = i + 1; j < length; j++)
                    edgs.add(new Edge(dist(points,i,j),i,j));
            edgs.sort(Comparator.comparingInt((Edge e)->e.len));
            for(Edge edg : edgs){
                if(unionFind.union(edg.x,edg.y)){
                    ++num;
                    ans += edg.len;
                    if(num == length)
                        break;
                }
            }
            return ans;
        }
        private int dist(int[][] points,int x,int y){
            return Math.abs(points[x][0] - points[y][0]) + Math.abs(points[x][1] - points[y][1]);
        }
    }
    
    class UnionFind{
        int[] parent;
        int[] rank;
    
        UnionFind(int n){
            parent = new int[n];
            rank = new int[n];
            for(int i = 0; i < n; i++){
                parent[i] = i;
                rank[i] = 1;
            }
        }
        
        boolean union(int x,int y){
            int rootX = find(x);
            int rootY = find(y);
            if(rootX == rootY)
                return false;
            if(rootX < rootY){
                rootX = rootX ^ rootY;
                rootY = rootX ^ rootY;
                rootX = rootX ^ rootY;
            }
            rank[rootX] += rank[rootY];
            parent[rootY] = rootX;
            return true;
        }
    
        private int find(int index){
            if(parent[index] != index)
                parent[index] = find(parent[index]);
            return parent[index];
        }
    }
    
    class Edge{
        int len,x,y;
        Edge(int len,int x,int y){
            this.len = len;
            this.x = x;
            this.y = y;
        }
    }
    

    方式二(prime):

    class Solution {
        public int minCostConnectPoints(int[][] points) {
            int[] lowCost = new int[points.length];
            int checkPoint = 0;
            int cost = 0;
            Arrays.fill(lowCost,Integer.MAX_VALUE);
            lowCost[0] = 0;
            for(int i = 0; i < points.length - 1; i++){
                int minCost = Integer.MAX_VALUE;
                int minPoint = 0;
                for(int j = 0; j < points.length; j++){
                    if(lowCost[j] != 0){
                        lowCost[j] = Math.min(lowCost[j],dist(points,checkPoint,j));
                        if(lowCost[j] < minCost){
                            minCost = lowCost[j];
                            minPoint = j;
                        }
                    }
                }
                checkPoint = minPoint;
                lowCost[minPoint] = 0;
                cost += minCost;
            }
            return cost;
        }
        private int dist(int[][] points,int x,int y){
            return Math.abs(points[x][0] - points[y][0]) + Math.abs(points[x][1] - points[y][1]);
        }
    }
    

    参考:

    https://leetcode-cn.com/problems/min-cost-to-connect-all-points/

  • 相关阅读:
    取出某块内存的二进制数据
    拷贝构造函数的第一个参数必须是自身类类型的引用
    大小端,memcpy和构造函数
    类型装换和内存数据显示
    ERROR: iterator not incrementable || iterator not decrementable
    什么时候删除指针后,要给指针赋NULL
    chapter11、4concurrent.future模块
    chapter11、3多进程 multiprocessing
    chapter8.3、二分查找
    chapter8.2、面向对象三要素--继承
  • 原文地址:https://www.cnblogs.com/CodingXu-jie/p/14301889.html
Copyright © 2011-2022 走看看