zoukankan      html  css  js  c++  java
  • 【leetcode】296.Best Meeting Point

    原题

    A group of two or more people wants to meet and minimize the total travel distance.
    You are given a 2D grid of values 0 or 1, where each 1 marks the home of someone in the group.
    The distance is calculated using Manhattan Distance,
    where distance(p1, p2) = |p2.x - p1.x| + |p2.y - p1.y|.

    For example, given three people living at (0,0), (0,4), and (2,2):

    1 - 0 - 0 - 0 - 1
    | | | | |
    0 - 0 - 0 - 0 - 0
    | | | | |
    0 - 0 - 1 - 0 - 0
    The point (0,2) is an ideal meeting point, as the total travel distance of 2+2+2=6 is minimal. So return 6.

    Hint:
    Try to solve it in one dimension first. How can this solution apply to the two dimension case?

    解析

    曼哈顿距离:即一个矩阵的矩阵方格边线距离,如上例中,(0,0)-(2,2)的距离为4
    该题求一个矩阵中的1位置到哪一个矩阵点的距离之和最小,并返回该距离
    如上例中,三个点(0,0)(0,4)(2,2) 到(0,2)距离之和最小,为6
    入参有两种表达:
    一是入参为矩阵点的二维数组,每个数组值为0/1
    二是入参为矩阵点的位置坐标,如上例中就是{{0,0},{0,4},{2,2}}

    我的解法

    没解出来,Hard难度的题真的不一样。。
    我来写下我看过答案后的思路
    原题的提示是将二维问题在一维先解决,再应用到二维上,意思就是先思考如何解决一条线上的点,求最短距离之和
    1、一条线上有2个点
    最短距离的点一定是这两个点的中点,则最短距离是两个点的直线距离
    2、一条线上有3个点
    最短距离是所有点到中间那个点的距离,还是最远的两个点的直线距离
    3、一条线上有4个点
    最短距离的点一定在最远的两个点之间,最远的两个点的距离就是固定的直线距离,那若要让中间两个点的距离最短,则最短距离点应该是中间两个点的中点,所以四个点的最短距离就是外部两点直线距离+内部两点直线距离
    以此类推,一条线上的点,要求最短距离点,一定是中间两点的中点(偶数个点),或最中间的一个点(奇数个点),最短距离算法就是,最外侧两点距离+次外层两点距离+...+最内侧两点距离的和(若有中点,距离为0可以省略)

    现在将问题扩展到二维,因为求的是曼哈顿距离,所以二维的最短距离也是在水平和垂直两个方向上的,所以只要求出水平的最短距离和垂直的最短距离,求和即可

    最优解法

    public class BestMeetingPoint {
        //以下代码以入参为矩阵二维数组来实现
        // O(MN)
        public static int minTotalDistance(int[][] grid) {
            //传入的矩阵是这样的   int[][] grid = { { 1, 0, 0, 0, 1 }, { 0, 0, 0, 0, 0 }, { 0, 0, 1, 0, 0 } };
            // means which row has the people on it
            List<Integer> row = new LinkedList();
            // means which col has the people on it
            List<Integer> col = new LinkedList();
            for (int i = 0; i < grid.length; i++) {
                for (int j = 0; j < grid[0].length; j++) {
                    if (grid[i][j] == 1) {
                        row.add(i);
                        col.add(j);
                    }
                }
            }
            // 分别放到一维上来做;
            return getMin(row) + getMin(col);
        }
    
        //一维距离算法
        private static int getMin(List<Integer> list) {
            int res = 0;
            Collections.sort(list);
            int i = 0, j = list.size() - 1;
            while (i < j) {
                res += list.get(j--) - list.get(i++);
            }
            return res;
        }
    }
    
  • 相关阅读:
    [每天进步一点 流水账]第4周
    单指令流多数据流( SIMD)
    [每天进步一点 流水账]第2周
    写时复制技术(COW)
    ECMAScript 运算符乘性运算符
    ECMAScript 运算符Boolean 运算符
    ECMAScript 基础保留字
    ECMAScript 基础关键字
    ECMAScript 运算符一元运算符
    ECMAScript 基础原始类型
  • 原文地址:https://www.cnblogs.com/shanelau/p/7125467.html
Copyright © 2011-2022 走看看