Build Post Office 系列 | Hyoung's Blog



Build Post Office 系列 | Hyoung's Blog

题设很简单

给定一个二维网格,每个格子要么是房子 1,要么是空地 0,我们需要找到一个空地盖邮局使得所有房子到邮局的距离总和最小。同时,房子和空地都可以随意通过。

在该题设中,因为房子并不会充当一个阻碍物,所以并不需要用 BFS 等算法来计算最短路径,简单地计算两个格子之间在网格上的曼哈顿距离(Manhattan distance)就好了,即

d(P,Q)=|P.xQ.x|+|P.yQ.y|

最先想到的就是暴力算法:穷举网格上的每一个空地,并计算所有房子到它的距离,最后取最小的一个即可。实现起来就是几个嵌套循环,就此略过。最糟糕的情况下时间复杂度为O(m2n2)

如果我们进一步观察,可以发现,若我们在同一行上移动,所有房子(H)到该行(r)的垂直距离(Y 轴方向)不变,其和也因此不变,即 abs(H(i).yr) 不变。同理,对于每一列也是如此。在同一列上移动,所有房子到该列的水平距离之和也不变。

充分利用上面的观察,我们就可以提出一个更好的算法,即先算出所有房子到每一行的距离之和以及每一列的距离之和,最后在网格上就可以很快的算出所有房子到某点的距离之和了。

想要算出所有房子到每一行或每一列的距离之和,我们可以进一步抽象,把问题转换成一维上的问题。以到每一行的距离之和为例。首先很直观就可以发现,对于任意两行上的点而言,其垂直距离都是固定不变的。于是我们可以进行水平方向的压缩(不需要水平坐标的信息了),即统计出每一行上的房子数目。而后,问题就变成了,在这个一维的线上算出所有点到任意一点的距离之和。利用前缀和(prefix sum),我们可以在O(n)的时间里解决。具体思路就是先从左边扫一遍,记录 [0,i) 范围内的点到 i 的距离之和,又是一个简单的动态规划了,其状态转移方程为

1
prefixCost[i] = prefixCost[i - 1] + prefixSum[i - 1]

其中,prefixSum[i]记录范围 [0,i] 之间点的个数。

类似的,再从右边扫一遍,记录 (i,n1] 范围内的点到 i 的距离之和。最后把左右结果相加即可。

整体而言,该算法的时间复杂度为O(mn)。具体代码实现如下


Read full article from Build Post Office 系列 | Hyoung's Blog


No comments:

Post a Comment

Labels

Algorithm (219) Lucene (130) LeetCode (97) Database (36) Data Structure (33) text mining (28) Solr (27) java (27) Mathematical Algorithm (26) Difficult Algorithm (25) Logic Thinking (23) Puzzles (23) Bit Algorithms (22) Math (21) List (20) Dynamic Programming (19) Linux (19) Tree (18) Machine Learning (15) EPI (11) Queue (11) Smart Algorithm (11) Operating System (9) Java Basic (8) Recursive Algorithm (8) Stack (8) Eclipse (7) Scala (7) Tika (7) J2EE (6) Monitoring (6) Trie (6) Concurrency (5) Geometry Algorithm (5) Greedy Algorithm (5) Mahout (5) MySQL (5) xpost (5) C (4) Interview (4) Vi (4) regular expression (4) to-do (4) C++ (3) Chrome (3) Divide and Conquer (3) Graph Algorithm (3) Permutation (3) Powershell (3) Random (3) Segment Tree (3) UIMA (3) Union-Find (3) Video (3) Virtualization (3) Windows (3) XML (3) Advanced Data Structure (2) Android (2) Bash (2) Classic Algorithm (2) Debugging (2) Design Pattern (2) Google (2) Hadoop (2) Java Collections (2) Markov Chains (2) Probabilities (2) Shell (2) Site (2) Web Development (2) Workplace (2) angularjs (2) .Net (1) Amazon Interview (1) Android Studio (1) Array (1) Boilerpipe (1) Book Notes (1) ChromeOS (1) Chromebook (1) Codility (1) Desgin (1) Design (1) Divide and Conqure (1) GAE (1) Google Interview (1) Great Stuff (1) Hash (1) High Tech Companies (1) Improving (1) LifeTips (1) Maven (1) Network (1) Performance (1) Programming (1) Resources (1) Sampling (1) Sed (1) Smart Thinking (1) Sort (1) Spark (1) Stanford NLP (1) System Design (1) Trove (1) VIP (1) tools (1)

Popular Posts