[LeetCode] 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:

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

这道题让我们求最佳的开会地点,该地点需要到每个为1的点的曼哈顿距离之和最小,题目中给了我们提示,让我们先从一维的情况来分析,那么我们先看一维时有两个点A和B的情况,

______A_____P_______B_______

那么我们可以发现,只要开会为位置P在[A, B]区间内,不管在哪,距离之和都是A和B之间的距离,如果P不在[A, B]之间,那么距离之和就会大于A和B之间的距离,那么我们现在再加两个点C和D:

______C_____A_____P_______B______D______

我们通过分析可以得出,P点的最佳位置就是在[A, B]区间内,这样和四个点的距离之和为AB距离加上CD距离,在其他任意一点的距离都会大于这个距离,那么分析出来了上述规律,这题就变得很容易了,我们只要给位置排好序,然后用最后一个坐标减去第一个坐标,即CD距离,倒数第二个坐标减去第二个坐标,即AB距离,以此类推,直到最中间停止,那么一维的情况分析出来了,二维的情况就是两个一维相加即可,参见代码如下:

解法一:

class Solution {
public:
    int minTotalDistance(vector<vector<int>>& grid) {
        vector<int> rows, cols;
        for (int i = 0; i < grid.size(); ++i) {
            for (int j = 0; j < grid[i].size(); ++j) {
                if (grid[i][j] == 1) {
                    rows.push_back(i);
                    cols.push_back(j);
                }
            }
        }
        return minTotalDistance(rows) + minTotalDistance(cols);
    }
    int minTotalDistance(vector<int> v) {
        int res = 0;
        sort(v.begin(), v.end());
        int i = 0, j = v.size() - 1;
        while (i < j) res += v[j--] - v[i++];
        return res;
    }
};

我们也可以不用多写一个函数,直接对rows和cols同时处理,稍稍能简化些代码:

解法二:

class Solution {
public:
    int minTotalDistance(vector<vector<int>>& grid) {
        vector<int> rows, cols;
        for (int i = 0; i < grid.size(); ++i) {
            for (int j = 0; j < grid[i].size(); ++j) {
                if (grid[i][j] == 1) {
                    rows.push_back(i);
                    cols.push_back(j);
                }
            }
        }
        sort(rows.begin(), rows.end());
        sort(cols.begin(), cols.end());
        int res = 0, i = 0, j = rows.size() - 1;
        while (i < j) res += rows[j] - rows[i] + cols[j--] - cols[i++];
        return res;
    }
};

参考资料:

https://leetcode.com/discuss/65336/14ms-java-solution

https://leetcode.com/discuss/85074/14-lines-concise-and-easy-understand-c-solution

LeetCode All in One 题目讲解汇总(持续更新中...)

时间: 2024-10-11 04:33:05

[LeetCode] Best Meeting Point 最佳开会地点的相关文章

LeetCode 252. Meeting Rooms (会议室)

Given an array of meeting time intervals consisting of start and end times [[s1,e1],[s2,e2],...] (si < ei), determine if a person could attend all meetings. For example,Given [[0, 30],[5, 10],[15, 20]],return false. 题目标签:sort 这道题目给了我们一个array的会议时间,让我们

[LeetCode#252] Meeting Rooms

Problem: Given an array of meeting time intervals consisting of start and end times [[s1,e1],[s2,e2],...] (si < ei), determine if a person could attend all meetings. For example,Given [[0, 30],[5, 10],[15, 20]],return false. Analysis: The problem is

[LeetCode#253] Meeting Rooms II

Problem: Given an array of meeting time intervals consisting of start and end times [[s1,e1],[s2,e2],...] (si < ei), find the minimum number of conference rooms required. For example,Given [[0, 30],[5, 10],[15, 20]],return 2. Analysis: This problem l

[LeetCode]Best Meeting Point

第一次一次过的hard题目,其实觉得难度应该算是中等难题.就是先找纵方向的中点,再找横方向的中点,思路类似一维的情况 public class Solution { public int minTotalDistance(int[][] grid) { int row = grid.length; if (row == 0) { return 0; } int col = grid[0].length; ArrayList<Integer> list_r = new ArrayList<

[Alpha阶段]第一次Scrum Meeting

Scrum Meeting博客目录 [Alpha阶段]第一次Scrum Meeting 基本信息 名称 时间 地点 时长 第一次Scrum Meeting 19/04/01 大运村寝室6楼 40min 相关工作 成员 已完成工作 明日计划工作 鲍屹伟 确定项目内内容,撰写需求文档,技术规格文档前端部分 确定每人具体工作,学习微信小程序开发基本知识 白世豪 确定项目内内容,确定前后端分工及基本框架,技术规格文档概述及组织 学习微信小程序前端及前后端交互知识,Alpha阶段页面跳转规划 刘启航 确定

[Alpha阶段]第二次Scrum Meeting

Scrum Meeting博客目录 [Alpha阶段]第二次Scrum Meeting 基本信息 名称 时间 地点 时长 第二次Scrum Meeting 19/04/04 大运村寝室6楼 90min 相关工作 成员 已完成工作 明日计划工作 鲍屹伟 确定每人具体工作,学习微信小程序开发基本知识 学习weapp,主要学习绘制界面,demo版总体规划 白世豪 学习微信小程序前端及前后端交互知识,Alpha阶段页面跳转规划 demo版前端页面制定,前端框架weapp学习 刘启航 学习微信小程序后端知

[Alpha阶段]第七次Scrum Meeting

Scrum Meeting博客目录 [Alpha阶段]第七次Scrum Meeting 基本信息 名称 时间 地点 时长 第七次Scrum Meeting 19/04/11 大运村寝室6楼 35min 相关工作 成员 已完成工作 明日计划工作 鲍屹伟 每日例会博客撰写,新建发布页面及功能完成 每日例会博客撰写,优化各页面布局.配色 白世豪 完成个人资料页面中的功能,我的发布页面及功能完成 完成修改发布页面及功能,完成发布的申请页面 刘启航 完成了发布部分的所有接口 添加后端功能,检查之前的各接口

[Beta阶段]第四次Scrum Meeting

Scrum Meeting博客目录 [Beta阶段]第四次Scrum Meeting 基本信息 名称 时间 地点 时长 第四次Scrum Meeting 19/05/06 大运村寝室6楼 30min 相关工作 成员 已完成工作 明日计划工作 鲍屹伟 每日例会撰写,发布详情页面重新绘制,我的发布页面重新绘制 每日例会撰写,tags具体内容确定,我的申请详情页面重新绘制 白世豪 我的发布页面重新绘制--完成基本布局 我的发布页面重新绘制--字号,button中文字位置与大小关系等调整 刘启航 学习如

[Beta阶段]第十一次Scrum Meeting

Scrum Meeting博客目录 [Beta阶段]第十一次Scrum Meeting 基本信息 名称 时间 地点 时长 第十一次Scrum Meeting 19/05/20 大运村寝室6楼 15min 相关工作 这次例会主要分配测试.发布阶段的具体任务. 成员 计划工作 鲍屹伟 发布说明.测试报告撰写 白世豪 进行前端各类机型上的测试并修改bug 刘启航 对现有新界面的各类功能进行录屏 刘卫 机型后端压力测试 王冰 进行前端各类机型上的测试并修改bug 宋卓洋 完善后端的单元测试,提高覆盖率