Facebook Pixel

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:

  1. Median is greater than k: If the median is greater than k, it means the elements on the right side are also either greater or equal to k. Thus, we need to focus on the elements to the left of the median that are greater than k and reduce them to k.

  2. Median is less than or equal to k: In this case, the elements on the left side are less than or equal to k. Therefore, we focus on those elements on the right of the median that are less than k and increase them to k.

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.

Learn more about Greedy and Sorting patterns.

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:

  1. 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.

  2. Identifying the Median: Once the array is sorted, we find the position of the median. For an array of size n, the median index m is calculated as n // 2. If the array has an even length, by problem definition, we consider the larger of the two central elements.

  3. 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 target k, represented as |nums[m] - k|.

  4. 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 of m. For every element greater than k, we reduce it to k, 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 of m. For every element less than k, we increase it to k, 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 Evaluator

Example 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 than k, so no change is necessary.
  • Element at index 4: 7

    • Since 7 > 5, it is already greater than k, so no change is necessary.

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.


Discover Your Strengths and Weaknesses: Take Our 2-Minute Quiz to Tailor Your Study Plan:
Question 1 out of 10

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

Want a Structured Path to Master System Design Too? Donโ€™t Miss This!


Load More