使数组中位数等于 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
数据结构
网络
关系数据库管理系统 (RDBMS)
操作系统
Java
iOS
HTML
CSS
Android
Python
C 编程
C++
C#
MongoDB
MySQL
Javascript
PHP