|
| 1 | +# Time: O(n) |
| 2 | +# Space: O(n) |
| 3 | + |
| 4 | +from random import randint |
| 5 | + |
| 6 | +class Solution(object): |
| 7 | + def minTotalDistance(self, grid): |
| 8 | + """ |
| 9 | + :type grid: List[List[int]] |
| 10 | + :rtype: int |
| 11 | + """ |
| 12 | + x = [i for i, row in enumerate(grid) for v in row if v == 1] |
| 13 | + y = [j for row in grid for j, v in enumerate(row) if v == 1] |
| 14 | + mid_x = self.findKthLargest(x, len(x) / 2 + 1) |
| 15 | + mid_y = self.findKthLargest(y, len(y) / 2 + 1) |
| 16 | + |
| 17 | + return sum([abs(mid_x-i) + abs(mid_y-j) \ |
| 18 | + for i, row in enumerate(grid) for j, v in enumerate(row) if v == 1]) |
| 19 | + |
| 20 | + def findKthLargest(self, nums, k): |
| 21 | + left, right = 0, len(nums) - 1 |
| 22 | + while left <= right: |
| 23 | + pivot_idx = randint(left, right) |
| 24 | + new_pivot_idx = self.PartitionAroundPivot(left, right, pivot_idx, nums) |
| 25 | + if new_pivot_idx == k - 1: |
| 26 | + return nums[new_pivot_idx] |
| 27 | + elif new_pivot_idx > k - 1: |
| 28 | + right = new_pivot_idx - 1 |
| 29 | + else: # new_pivot_idx < k - 1. |
| 30 | + left = new_pivot_idx + 1 |
| 31 | + |
| 32 | + def PartitionAroundPivot(self, left, right, pivot_idx, nums): |
| 33 | + pivot_value = nums[pivot_idx] |
| 34 | + new_pivot_idx = left |
| 35 | + nums[pivot_idx], nums[right] = nums[right], nums[pivot_idx] |
| 36 | + for i in xrange(left, right): |
| 37 | + if nums[i] > pivot_value: |
| 38 | + nums[i], nums[new_pivot_idx] = nums[new_pivot_idx], nums[i] |
| 39 | + new_pivot_idx += 1 |
| 40 | + |
| 41 | + nums[right], nums[new_pivot_idx] = nums[new_pivot_idx], nums[right] |
| 42 | + return new_pivot_idx |
0 commit comments