使数组中位数等于 K 的最小操作数


问题“使数组中位数等于 K 的最小操作数”用于调整整数数组的元素,使其中位数等于给定值 k。在一次操作中,您可以将任何元素增加或减少 1。

问题陈述

目标是找到使数组中位数等于 K 的最小操作数。数组的中位数是在数组按非递减顺序排序时位于中间的元素。如果存在两个中间元素,则较大的一个被认为是中位数。

示例场景 1

Input: nums = [7, 1, 4], k = 5

Output: 1

排序后的数组 = [1, 4, 7],中位数 = 4,操作 = 将 4 增加到 5(1 次操作),总操作数 = 1。

示例场景 2

Input: nums = [10, 2, 8, 6, 4], k = 6

Output: 0

排序后的数组 = [2, 4, 6, 8, 10],中位数 = 6。不需要操作,因为中位数已经是 6。

示例场景 3

Input: nums = [20, 5, 15, 10, 25], k = 18

Output: 3

排序后的数组 = [5, 10, 15, 20, 25],中位数 = 15,操作 = 将 15 增加到 18(15(+1+1+1): 3 次操作),总操作数 = 3。

示例场景 4

Input: nums = [12, 3, 2, 9, 5, 11 ], k = 9

Output: 0

排序后的数组 = [2, 3, 5, 9, 11, 12],中位数 = 9,不需要执行操作,因为它已经等于中位数。此处 5, 9 是中位数,因为 9 最大,它是中位数且等于 k。

时间复杂度

对 (n) 个元素的数组进行排序的时间复杂度为 O(n log n),计算中位数需要遍历数组,这需要 O(n) 的时间,其中 n 是操作数。

为了用各种编程语言解决这个问题,可以使用以下方法。
  • 排序和二分查找
  • 双指针技术

排序和二分查找

示例

以下方法对数组进行排序以查找中位数,并使用二分查找来查找使中位数等于 k 所需操作数最少的最佳值。

#include <iostream>
#include <vector>
#include <algorithm>

int minOperationsToMedian(std::vector<int>& nums, int K) {
   std::sort(nums.begin(), nums.end());
   int n = nums.size();
   int medianIndex = n / 2;
   int operations = 0;

   if (nums[medianIndex] != K) {
      operations = std::abs(nums[medianIndex] - K);
   }

   return operations;
}

int main() {
   std::vector<int> nums = {20, 5, 15, 10, 25};
   int K = 18;
   std::cout << "Minimum operations = " << minOperationsToMedian(nums, K) << std::endl;
   return 0;
}
         

输出

Minimum operations = 3
import java.util.Arrays;

public class MinOperationsToMedian {
   public static int minOperationsToMedian(int[] nums, int K) {
      Arrays.sort(nums);
      int n = nums.length;
      int medianIndex = n / 2;
      int operations = 0;
   
      if (nums[medianIndex] != K) {
         operations = Math.abs(nums[medianIndex] - K);
      }
   
      return operations;
   }
   
   public static void main(String[] args) {
      int[] nums = {20, 5, 15, 10, 25};
      int K = 18;
      System.out.println("Minimum operations = " + minOperationsToMedian(nums, K));
   }
}
         

输出

Minimum operations = 3
def min_operations_to_median(nums, K):
   nums.sort()
   n = len(nums)
   median_index = n // 2
   operations = 0

   if nums[median_index] != K:
      operations = abs(nums[median_index] - K)

   return operations

nums = [20, 5, 15, 10, 25]
K = 18
print("Minimum operations = ", min_operations_to_median(nums, K))
         

输出

Minimum operations = 3
package main

import (
   "fmt"
   "math"
   "sort"
)

func minOperationsToMedian(nums []int, K int) int {
   sort.Ints(nums)
   n := len(nums)
   medianIndex := n / 2
   operations := 0

   if nums[medianIndex] != K {
      operations = int(math.Abs(float64(nums[medianIndex] - K)))
   }

   return operations
}

func main() {
   nums := []int{20, 5, 15, 10, 25}
   K := 18
   fmt.Println("Minimum operations =", minOperationsToMedian(nums, K))
}
         

输出

Minimum operations = 3

双指针技术

示例

在这种技术中,我们使用两个指针来识别排序数组中的中位数位置,并调整中位数两侧的元素以使中位数等于 k。

#include <bits/stdc++.h>
using namespace std;

int minOperationsToMakeMedianK(vector<int>& nums, int k) {
   sort(nums.begin(), nums.end());
   int n = nums.size();
   int operations = 0;

   for (int i = 0; i < n / 2; ++i) {
      operations += max(0, nums[i] - k);
   }
   for (int i = n / 2; i < n; ++i) {
      operations += max(0, k - nums[i]);
   }

   return operations;
}

int main() {
   vector<int> nums = {20, 5, 15, 10, 25};
   int k = 18;
   cout <<"Minimum operations = " << minOperationsToMakeMedianK(nums, k) << endl;
   return 0;
}
         

输出

Minimum operations = 3
import java.util.Arrays;

public class Main {
   public static int minOperationsToMakeMedianK(int[] nums, int k) {
      Arrays.sort(nums);
      int n = nums.length;
      int operations = 0;

      for (int i = 0; i < n / 2; ++i) {
         operations += Math.max(0, nums[i] - k);
      }
      for (int i = n / 2; i < n; ++i) {
         operations += Math.max(0, k - nums[i]);
      }

      return operations;
   }

   public static void main(String[] args) {
      int[] nums = {20, 5, 15, 10, 25};
      int k = 18;
      System.out.println("Minimum operations = " + minOperationsToMakeMedianK(nums, k));
   }
}
         

输出

Minimum operations = 3
import math

def min_operations_to_make_median_k(nums, k):
   nums.sort()
   n = len(nums)
   operations = 0

   for i in range(n // 2):
      operations += max(0, nums[i] - k)
   for i in range(n // 2, n):
      operations += max(0, k - nums[i])

   return operations

nums = [20, 5, 15, 10, 25]
k = 18
print(f"Minimum operations = {min_operations_to_make_median_k(nums, k)}")
         

输出

Minimum operations = 3
package main

import (
   "fmt"
   "sort"
)

func minOperationsToMakeMedianK(nums []int, k int) int {
   sort.Ints(nums)
   n := len(nums)
   operations := 0

   for i := 0; i < n/2; i++ {
      operations += max(0, nums[i]-k)
   }
   for i := n / 2; i < n; i++ {
      operations += max(0, k-nums[i])
   }

   return operations
}

func max(a, b int) int {
   if a > b {
      return a
   }
   return b
}

func main() {
   nums := []int{20, 5, 15, 10, 25}
   k := 18
   fmt.Println("Minimum operations =", minOperationsToMakeMedianK(nums, k))
}
         

输出

Minimum operations = 3

Revathi Satya Kondra
Revathi Satya Kondra

Tutorialspoint 技术内容撰写人

更新于:2024年7月23日

浏览量:55

开启您的职业生涯

完成课程获得认证

开始学习
广告
© . All rights reserved.