|
| 1 | +/** |
| 2 | + * 1515. Best Position for a Service Centre |
| 3 | + * https://leetcode.com/problems/best-position-for-a-service-centre/ |
| 4 | + * Difficulty: Hard |
| 5 | + * |
| 6 | + * A delivery company wants to build a new service center in a new city. The company knows the |
| 7 | + * positions of all the customers in this city on a 2D-Map and wants to build the new center in |
| 8 | + * a position such that the sum of the euclidean distances to all customers is minimum. |
| 9 | + * |
| 10 | + * Given an array positions where positions[i] = [xi, yi] is the position of the ith customer on |
| 11 | + * the map, return the minimum sum of the euclidean distances to all customers. |
| 12 | + * |
| 13 | + * In other words, you need to choose the position of the service center [xcentre, ycentre] such |
| 14 | + * that the following formula is minimized: |
| 15 | + * - Answers within 10-5 of the actual value will be accepted. |
| 16 | + */ |
| 17 | + |
| 18 | +/** |
| 19 | + * @param {number[][]} positions |
| 20 | + * @return {number} |
| 21 | + */ |
| 22 | +var getMinDistSum = function(positions) { |
| 23 | + const n = positions.length; |
| 24 | + let xSum = 0; |
| 25 | + let ySum = 0; |
| 26 | + |
| 27 | + for (const [x, y] of positions) { |
| 28 | + xSum += x; |
| 29 | + ySum += y; |
| 30 | + } |
| 31 | + |
| 32 | + let xCenter = xSum / n; |
| 33 | + let yCenter = ySum / n; |
| 34 | + const epsilon = 1e-7; |
| 35 | + const maxIterations = 1000; |
| 36 | + |
| 37 | + for (let iter = 0; iter < maxIterations; iter++) { |
| 38 | + let xNumerator = 0; |
| 39 | + let yNumerator = 0; |
| 40 | + let denominator = 0; |
| 41 | + |
| 42 | + for (const [x, y] of positions) { |
| 43 | + const dx = xCenter - x; |
| 44 | + const dy = yCenter - y; |
| 45 | + const dist = Math.sqrt(dx * dx + dy * dy); |
| 46 | + if (dist < epsilon) continue; |
| 47 | + const weight = 1 / dist; |
| 48 | + xNumerator += x * weight; |
| 49 | + yNumerator += y * weight; |
| 50 | + denominator += weight; |
| 51 | + } |
| 52 | + |
| 53 | + if (denominator < epsilon) break; |
| 54 | + |
| 55 | + const newX = xNumerator / denominator; |
| 56 | + const newY = yNumerator / denominator; |
| 57 | + |
| 58 | + if (Math.abs(newX - xCenter) < epsilon && Math.abs(newY - yCenter) < epsilon) { |
| 59 | + break; |
| 60 | + } |
| 61 | + |
| 62 | + xCenter = newX; |
| 63 | + yCenter = newY; |
| 64 | + } |
| 65 | + |
| 66 | + let sumDist = 0; |
| 67 | + for (const [x, y] of positions) { |
| 68 | + sumDist += Math.sqrt((xCenter - x) ** 2 + (yCenter - y) ** 2); |
| 69 | + } |
| 70 | + |
| 71 | + return sumDist; |
| 72 | +}; |
0 commit comments