3107 Minimum Operations to Make Median of Array Equal to K
My intuition is that, it's a prefix sum problem since it has keyword make median of array equal to K, but it's not asking for anything related to subarray. So i didn't go that direction.
In the dry run, to determine the number of operations, on the paper, I will sort it first, since it's easier to look at it that way. Then find the median, then calculate the number of operations. So it occurs to me that whether i could afford to sort it. Look at the constrains
- n <= \(10^5\)
- 1 <= nums[i] <= \(10^9\)
- k <= \(10^9\)
So, after sort, \(O(nlogn)\) would be like on the worst possible case that we can AC it. So i went down the sorting route.
Approach 1 Sorting
I draw a little diagram to help me understand the problem better. I drew the array and the vertical line of k, then i drew the median line. We can't modify the k so we have to modify the nums for us to move the vertical line to desired location.

Your goal is to move the curr_i to target_i by subtracting or adding the numbers in between curr_i and target_i, i.e. nums[left:right]. The number of operations is the sum of the absolute difference between the nums and k in the range of the median.
Tip
只要y = k这根线,在sorted(nums)中,至少有一半的数在这根线的左边,那么就可以让y=k成为改造后的median。所以我们定义的时候,是[left,right)的左闭右开区间
Steps:
- sort the
nums - find the
curr_idefined as the index wherekshould be inserted in sortednums - find the
target_idefined as the index that the median should be
class Solution:
def minOperationsToMakeMedianK(self, nums: List[int], k: int) -> int:
nums.sort()
n = len(nums)
# find location of k in sorted(nums)
if k < nums[0]:
curr_i = 0
elif k >= nums[-1]:
curr_i = n
else:
for i in range(1,n):
prev = nums[i-1]
curr = nums[i]
if k < curr and k >= prev:
curr_i = i
break
# find where the index should be
if curr_i >= n//2 + 1:
target_i = n//2
else:
target_i = n//2 +1
res = [abs(num - k) for num in nums[min(curr_i,target_i):max(curr_i,target_i)]]
return sum(res)