• leetcode 1584 连接所有点的最小费用


    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
    解释:

    我们可以按照上图所示连接所有点得到最小总费用,总费用为 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
    -106 <= xi, yi <= 106
    所有点 (xi, yi) 两两不同。

    package com.example.lettcode.dailyexercises;
    
    import java.util.Arrays;
    import java.util.Comparator;
    
    /**
     * @Class MinCostConnectPoints
     * @Description 1584 连接所有点的最小费用
    
     * @Author
     * @Date 2021/1/19
     **/
    public class MinCostConnectPoints {
        private static class Edge {
            int p1;
            int p2;
            int distance;
    
            public Edge(int p1, int p2, int distance) {
                this.p1 = p1;
                this.p2 = p2;
                this.distance = distance;
            }
        }
    
        /**
         * 找到target在并查集中对应的root节点
         *
         * @param target
         * @param rec
         * @return
         */
        public static int find(int target, int[] rec) {
            int root = target;
            /**
             * 一层一层向上找到所对应的根节点
             */
            while (root != rec[root]) {
                root = rec[root];
            }
            // 更新并查集
            int cur = target;
            while (cur != rec[cur]) {
                rec[cur] = root;
                cur = rec[cur];
            }
            return root;
        }
    
        /**
         * 判断两个点的根是否相同,不同则表示没有连接在树内
         *
         * @param p1
         * @param p2
         * @param rec 并查集,对于每个点都记录其对应的root节点
         * @return
         */
        public static boolean union(int p1, int p2, int[] rec) {
            int rootP1 = find(p1, rec);
            int rootP2 = find(p2, rec);
    
            rec[rootP1] = rootP2;// 两个根节点指向一起
            return rootP1 == rootP2;
        }
    
        /**
         * 克鲁斯卡尔算法
         *
         * @param points
         * @return
         */
        public static int kruskal(int[][] points) {
            int length = points.length;
            Edge[] edges = new Edge[length * length];
    
            // 初始化距离数组
            for (int i = 0; i < length; i++) {
                for (int j = 0; j < length; j++) {
                    // 计算出两点之间的距离
                    int distance = i == j ? Integer.MAX_VALUE : Math.abs(points[i][0] - points[j][0]) + Math.abs(points[i][1] - points[j][1]);
                    // 初始化距离数组
                    edges[i * length + j] = new Edge(i, j, distance);
                }
            }
            // 根据距离进行排序
            Arrays.sort(edges, new Comparator<Edge>() {
                @Override
                public int compare(Edge o1, Edge o2) {
                    return o1.distance - o2.distance;
                }
            });
    
            // 初始化并查集数组
            int[] rec = new int[length];
            for (int i = 0; i < length; i++) {
                rec[i] = i;
            }
            int count = 0;
            int cost = 0;
            for (int i = 0; i < edges.length && count < length - 1; i++) {
                Edge edge = edges[i];
                int p1 = edge.p1;
                int p2 = edge.p2;
                if (union(p1, p2, rec) == false) {
                    ++count;
                    cost += edge.distance;
                }
            }
            return cost;
        }
    
        public static int minCostConnectPoints(int[][] points) {
            return kruskal(points);
        }
    }
    
    // 测试用例
    public static void main(String[] args) {
    	int[][] points = new int[][]{{0, 0}, {2, 2}, {3, 10}, {5, 2}, {7, 0}};
    	int ans = minCostConnectPoints(points);
    	System.out.println("MinCostConnectPoints demo01 result:" + ans);
    
    	points = new int[][]{{3, 12}, {-2, 5}, {-4, 1}};
    	ans = minCostConnectPoints(points);
    	System.out.println("MinCostConnectPoints demo02 result:" + ans);
    
    	points = new int[][]{{0, 0}, {1, 1}, {1, 0}, {-1, 1}};
    	ans = minCostConnectPoints(points);
    	System.out.println("MinCostConnectPoints demo03 result:" + ans);
    
    	points = new int[][]{{-1000000, -1000000}, {1000000, 1000000}};
    	ans = minCostConnectPoints(points);
    	System.out.println("MinCostConnectPoints demo04 result:" + ans);
    
    	points = new int[][]{{0, 0}};
    	ans = minCostConnectPoints(points);
    	System.out.println("MinCostConnectPoints demo05 result:" + ans);
    }
    
  • 相关阅读:
    CSS3清除浮动3种方法
    CSS3浮动float
    CSS选择器伪类选择器(深度探索)
    CSS选择器孩子孙子兄弟(> ~ +)
    CSS权重问题
    CSS3定位
    Webpack 打包 6. 配置 devServer 用来自动化(自动编译,自动打开浏览器,自动刷新浏览器~~)
    Webpack 打包 7.webpack 开发环境配置
    Webpack 打包 4.webpack 图片资源打包
    JS模块化4 CMDSeaJS
  • 原文地址:https://www.cnblogs.com/fyusac/p/14298020.html
Copyright © 2020-2023  润新知