3107. Minimum Operations to Make Median of Array Equal to K
Problem Description
You are given an integer array nums
and a non-negative integer k
. In one operation, you can increase or decrease any element by 1. Return the minimum number of operations needed to make the median of nums
equal to k
.
The median of an array is defined as the middle element of the array when it is sorted in non-decreasing order. If there are two choices for a median, the larger of the two values is taken.
Intuition
To solve the problem of making the median of nums
equal to k
with the minimum number of operations, we start by sorting the array. Sorting helps in easily identifying the median of the array. The position of the median in a sorted array is the middle element if the length of nums
is odd, or the larger of the two middle elements if nums
has an even length.
Once the median is identified, we calculate the absolute difference between the median and k
, which is the minimum number of operations required if no other changes are needed.
From here, two scenarios arise:
-
Median is greater than
k
: If the median is greater thank
, it means the elements on the right side are also either greater or equal tok
. Thus, we need to focus on the elements to the left of the median that are greater thank
and reduce them tok
. -
Median is less than or equal to
k
: In this case, the elements on the left side are less than or equal tok
. Therefore, we focus on those elements on the right of the median that are less thank
and increase them tok
.
By following these steps, we ensure that the least number of operations are used while conforming to the given condition of making the median equal to k
.
Solution Approach
The solution to this problem involves a combination of sorting, greedy algorithm, and simple arithmetic calculations. Here's a detailed breakdown of the approach:
-
Sorting the Array: We begin by sorting the array
nums
in non-decreasing order. Sorting is crucial as it helps us determine the median directly depending on the length of the array. -
Identifying the Median: Once the array is sorted, we find the position of the median. For an array of size
n
, the median indexm
is calculated asn // 2
. If the array has an even length, by problem definition, we consider the larger of the two central elements. -
Initial Calculation of Operations: We compute the initial number of operations needed by taking the absolute difference between the median value
nums[m]
and the targetk
, represented as|nums[m] - k|
. -
Adjusting Elements Based on Median Comparison:
-
If
nums[m] > k
: It indicates that elements to the right of the median are already >=k
. Therefore, we iterate through the elements to the left ofm
. For every element greater thank
, we reduce it tok
, and add the difference to our operations count. -
If
nums[m] <= k
: In this case, elements to the left of the median are already <=k
. We then loop over the elements to the right ofm
. For every element less thank
, we increase it tok
, and include the difference in our operations count.
-
By using this strategy, the algorithm efficiently ensures the minimum operations needed to adjust the median to k
, handling both scenarios elegantly.
Ready to land your dream job?
Unlock your dream job with a 2-minute evaluator for a personalized learning plan!
Start EvaluatorExample Walkthrough
Consider the array nums = [6, 1, 3, 2, 7]
and k = 5
. Our goal is to make the median of nums
equal to k
with the minimum number of operations, where an operation is defined as increasing or decreasing any element by 1.
Step 1: Sorting the Array
First, sort the array nums
:
[ \text{Sorted } nums = [1, 2, 3, 6, 7] ]
Step 2: Identifying the Median
The median is the middle element of the sorted array. Since nums
has 5 elements (an odd number), the median is the element at index m = 5 // 2 = 2
. Thus, the median is 3
.
Step 3: Initial Calculation of Operations
Calculate the initial number of operations needed to adjust the median to k
. This is given by:
[ | \text{median} - k| = |3 - 5| = 2 ]
Step 4: Adjusting Elements Based on Median Comparison
Since 3
(the median) is less than k = 5
, we need to focus on elements to the right of the median (i.e., those at indices greater than 2):
-
Element at index 3:
6
- Since
6 > 5
, it is already greater thank
, so no change is necessary.
- Since
-
Element at index 4:
7
- Since
7 > 5
, it is already greater thank
, so no change is necessary.
- Since
For elements to the left of the median, they are already less than or equal to k
, so no changes are needed there either. Therefore, the minimum number of operations required remains 2, which was calculated initially.
Thus, the final answer is 2 operations to make the median equal to k
.
Solution Implementation
1from typing import List
2
3class Solution:
4 def minOperationsToMakeMedianK(self, nums: List[int], k: int) -> int:
5 # First, sort the array to easily find the median
6 nums.sort()
7 n = len(nums)
8
9 # The median index is calculated as half of the list length
10 m = n >> 1
11
12 # Calculate the initial difference between the median and k
13 ans = abs(nums[m] - k)
14
15 # If the median is greater than k, we need to reduce elements on the left side
16 if nums[m] > k:
17 for i in range(m - 1, -1, -1):
18 # Stop if the current element is less than or equal to k
19 if nums[i] <= k:
20 break
21 # Add the operations needed to make current element equal to k
22 ans += nums[i] - k
23
24 # If the median is less than or equal to k, we may need to increase elements on the right side
25 else:
26 for i in range(m + 1, n):
27 # Stop if the current element is greater than or equal to k
28 if nums[i] >= k:
29 break
30 # Add the operations needed to make current element equal to k
31 ans += k - nums[i]
32
33 # Return the total number of operations
34 return ans
35
1import java.util.Arrays;
2
3class Solution {
4 public long minOperationsToMakeMedianK(int[] nums, int k) {
5 // Sort the array to find the median
6 Arrays.sort(nums);
7 int n = nums.length;
8
9 // Find the middle index (median) of the sorted array
10 int medianIndex = n / 2;
11
12 // Initialize the result with the absolute difference between the median and k
13 long operations = Math.abs(nums[medianIndex] - k);
14
15 // If median is greater than k, decrease elements from the left side of the median
16 if (nums[medianIndex] > k) {
17 for (int i = medianIndex - 1; i >= 0 && nums[i] > k; --i) {
18 operations += nums[i] - k; // Add to operations the difference needed to make nums[i] equal to k
19 }
20 } else { // If median is less than or equal to k, increase elements from the right side of the median
21 for (int i = medianIndex + 1; i < n && nums[i] < k; ++i) {
22 operations += k - nums[i]; // Add to operations the difference needed to make nums[i] equal to k
23 }
24 }
25
26 // Return the total number of operations needed
27 return operations;
28 }
29}
30
1class Solution {
2public:
3 long long minOperationsToMakeMedianK(vector<int>& nums, int k) {
4 // Sort the vector nums to process it in a sorted manner
5 sort(nums.begin(), nums.end());
6
7 int n = nums.size(); // Get the size of the vector
8 int m = n >> 1; // Get the index of the median in the sorted array
9
10 // Calculate the initial operations needed to make the median equal to k
11 long long operations = abs(nums[m] - k);
12
13 // If the median is greater than k, adjust numbers before the median
14 if (nums[m] > k) {
15 // Traverse backward to find all numbers greater than k
16 for (int i = m - 1; i >= 0 && nums[i] > k; --i) {
17 // Accumulate the differences as they need to be reduced to k
18 operations += nums[i] - k;
19 }
20 } else { // If the median is less than or equal to k, adjust numbers after the median
21 // Traverse forward to find all numbers less than k
22 for (int i = m + 1; i < n && nums[i] < k; ++i) {
23 // Accumulate the differences as they need to be increased to k
24 operations += k - nums[i];
25 }
26 }
27
28 // Return the total operations calculated
29 return operations;
30 }
31};
32
1function minOperationsToMakeMedianK(nums: number[], k: number): number {
2 // Sort the array in non-decreasing order
3 nums.sort((a, b) => a - b);
4
5 const n = nums.length;
6 const m = Math.floor(n / 2); // Find the index of the median element
7
8 // Calculate initial operations needed to make the median equal to k
9 let operations = Math.abs(nums[m] - k);
10
11 // If the median is greater than k, adjust left half
12 if (nums[m] > k) {
13 for (let i = m - 1; i >= 0 && nums[i] > k; --i) {
14 operations += nums[i] - k; // Decrease each element greater than k to k
15 }
16 } else { // If the median is less than or equal to k, adjust right half
17 for (let i = m + 1; i < n && nums[i] < k; ++i) {
18 operations += k - nums[i]; // Increase each element less than k to k
19 }
20 }
21
22 return operations; // Return the total number of operations
23}
24
Time and Space Complexity
The given code first sorts the nums
list, which has a time complexity of O(n \log n)
, where n
is the length of the list. After sorting, the code calculates the minimum operations required by iterating over a portion of the list, which takes O(n)
time in the worst case. Therefore, the overall time complexity is O(n \log n)
.
The space complexity is O(\log n)
due to the space used by the sorting algorithm (if Timsort is assumed for Python's built-in sort, which is O(\log n)
for the recursive stack).
Therefore, the time complexity is O(n \log n)
and the space complexity is O(\log n)
.
Learn more about how to find time and space complexity quickly.
What's the output of running the following function using input [30, 20, 10, 100, 33, 12]
?
1def fun(arr: List[int]) -> List[int]:
2 import heapq
3 heapq.heapify(arr)
4 res = []
5 for i in range(3):
6 res.append(heapq.heappop(arr))
7 return res
8
1public static int[] fun(int[] arr) {
2 int[] res = new int[3];
3 PriorityQueue<Integer> heap = new PriorityQueue<>();
4 for (int i = 0; i < arr.length; i++) {
5 heap.add(arr[i]);
6 }
7 for (int i = 0; i < 3; i++) {
8 res[i] = heap.poll();
9 }
10 return res;
11}
12
1class HeapItem {
2 constructor(item, priority = item) {
3 this.item = item;
4 this.priority = priority;
5 }
6}
7
8class MinHeap {
9 constructor() {
10 this.heap = [];
11 }
12
13 push(node) {
14 // insert the new node at the end of the heap array
15 this.heap.push(node);
16 // find the correct position for the new node
17 this.bubble_up();
18 }
19
20 bubble_up() {
21 let index = this.heap.length - 1;
22
23 while (index > 0) {
24 const element = this.heap[index];
25 const parentIndex = Math.floor((index - 1) / 2);
26 const parent = this.heap[parentIndex];
27
28 if (parent.priority <= element.priority) break;
29 // if the parent is bigger than the child then swap the parent and child
30 this.heap[index] = parent;
31 this.heap[parentIndex] = element;
32 index = parentIndex;
33 }
34 }
35
36 pop() {
37 const min = this.heap[0];
38 this.heap[0] = this.heap[this.size() - 1];
39 this.heap.pop();
40 this.bubble_down();
41 return min;
42 }
43
44 bubble_down() {
45 let index = 0;
46 let min = index;
47 const n = this.heap.length;
48
49 while (index < n) {
50 const left = 2 * index + 1;
51 const right = left + 1;
52
53 if (left < n && this.heap[left].priority < this.heap[min].priority) {
54 min = left;
55 }
56 if (right < n && this.heap[right].priority < this.heap[min].priority) {
57 min = right;
58 }
59 if (min === index) break;
60 [this.heap[min], this.heap[index]] = [this.heap[index], this.heap[min]];
61 index = min;
62 }
63 }
64
65 peek() {
66 return this.heap[0];
67 }
68
69 size() {
70 return this.heap.length;
71 }
72}
73
74function fun(arr) {
75 const heap = new MinHeap();
76 for (const x of arr) {
77 heap.push(new HeapItem(x));
78 }
79 const res = [];
80 for (let i = 0; i < 3; i++) {
81 res.push(heap.pop().item);
82 }
83 return res;
84}
85
Recommended Readings
Greedy Introduction div class responsive iframe iframe src https www youtube com embed WTslqPbj7I title YouTube video player frameborder 0 allow accelerometer autoplay clipboard write encrypted media gyroscope picture in picture web share allowfullscreen iframe div When do we use greedy Greedy algorithms tend to solve optimization problems Typically they will ask you to calculate the max min of some value Commonly you may see this phrased in the problem as max min longest shortest largest smallest etc These keywords can be identified by just scanning
Sorting Summary Comparisons We presented quite a few sorting algorithms and it is essential to know the advantages and disadvantages of each one The basic algorithms are easy to visualize and easy to learn for beginner programmers because of their simplicity As such they will suffice if you don't know any advanced
Coding Interview Patterns Your Personal Dijkstra's Algorithm to Landing Your Dream Job The goal of AlgoMonster is to help you get a job in the shortest amount of time possible in a data driven way We compiled datasets of tech interview problems and broke them down by patterns This way
Want a Structured Path to Master System Design Too? Donโt Miss This!