美文网首页
凑数使数组中位数为特定值问题

凑数使数组中位数为特定值问题

作者: 陈大吼 | 来源:发表于2022-08-18 10:57 被阅读0次

题目描述:
小M给你一个长度为n的数组,我们定义median数为该数组从小到大排序后,下标为(n-1)/2的数字。下标从0开始,(n-1)/2表示整数除法,即向下取整。现在我们已经得到了一个初始的数组,我们希望这个数组的median数是一个给定数字x。所以我们需要加入一些数到数组中从而完成我们的目标。数组中的元素可以重复,请问,最少需要加入多少个数字才能达成这个目标。

输入描述:
第一行输入两个整数n x (1 <= n <= 500, 1 <= x <= 10^5)。
接下来一行有n个正整数表示初始的数组,用空格分开,范围是[1, 10^5]。

输出描述:
输出需要加入最少的元素个数才能够使得新数组的median数成为x。

示例1:
输入
3 2
2 3 4
输出
1
说明:加入1,得到1 2 3 4,那么median数的下标为(4 - 1)/2 = 1, median数为2。加一个数字就可以了。

示例2:
3 4
1 2 3
输出
4
说明:加入4 5 6 7,得到1 2 3 4 5 6 7,median数为4。最少加4个数字。

解法1:

import java.util.*;
public class Main {
    public static void main(String[] args) {
        Scanner scaner = new Scanner(System.in);
        int n = scaner.nextInt();
        int x =  scaner.nextInt();
        ArrayList<Integer> nums = new ArrayList();
        boolean exist = false;
        for(int i=0; i<n; i++) {
            int temp = scaner.nextInt();
            nums.add(temp);
            if(temp == x) {
                exist = true;
            }
        }
        int ans = 0;
        if(!exist) { //不存在时,至少需要加一个。提前加好,为了使后面相等的情况一定存在
            nums.add(x);
            ans++;
        }
        nums.sort(Comparator.naturalOrder());
        //以下两个while都一定是以相等的方式退出循序
        while(nums.get((nums.size()-1)/2) > x) {
            nums.add(0, 1);//用最小可能的值1,或者用nums[0],保证数组仍然有序
            ans++;
        }
        while(nums.get((nums.size()-1)/2) < x) {//前面是相等退出,所以如果前面循环执行了,后面的就不会执行
            nums.add(100000);//用最大可能的值100000,或者用nums[nums.size()-1],保证数组仍然有序
            ans++;
        }
        //直接满足nums.get((nums.size()-1)/2) == x的话,前面两个循环就都不会走
        System.out.println(ans);
    }
}

解法二:进一步简化

import java.util.*;
public class Main {
    public static void main(String[] args) {
        Scanner scaner = new Scanner(System.in);
        int n = scaner.nextInt();
        int x =  scaner.nextInt();
        int less = 0, greater = 0, equal = 0;//
        for(int i=0; i<n; i++) {
            int temp = scaner.nextInt();
            if(temp < x) {
                less++;
            } else if(temp == x) {
                equal++;
            } else {
                greater++;
            }
        }
        int m = (n-1)/2;
        if(m < less) {
            //m范围是[0,less-1],意味着m落在了less(比x小)队列中;
            //此时需要使equal最左边的数字(定义为E0)成为中位数,需要在E0右边增加数字
            //(可以理解为增加值x,这样equal=0的时候也适配此规则)
            //依照最少增加原则,使得增加后,E0左边的数字数和右边数字数相等即可
            //所以增加个数=E0当前左边的数字数-E0当前右边的数字数=less-(equal-1+greater)
            System.out.println(less-(equal-1+greater));
        } else if(m < less+equal) {
            //m范围是[less,less+equal-1],意味着m落在了equal(与x相等)队列中;此处不需要增加数字
            System.out.println(0);
        } else {
            //m范围是[less+equal,less+equal+greater-1],意味着m落在了greater(比x大)队列中;
            //此时需要使equal最右边的数字(定义为EL)成为中位数,需要在EL左边增加数字
            //(可以理解为增加值x,这样equal=0的时候也适配此规则)
            //依照最少增加原则,使得增加后,EL左边的数字数比右边数字数少一个即可(数组总个数为偶数时,中位数左边比右边少一个数)
            //所以增加个数=(EL当前右边的数字数-1)-E0当前左边的数字数=greater-1-(less+equal-1)
            System.out.println(greater-1-(less+equal-1));
        }
    }
}

相关文章

  • 凑数使数组中位数为特定值问题

    题目描述:小M给你一个长度为n的数组,我们定义median数为该数组从小到大排序后,下标为(n-1)/2的数字。下...

  • Lintcode-中位数

    问题描述: 给定一个未排序的整数数组,找到其中位数。中位数是排序后数组的中间值,如果数组的个数是偶数个,则返回排序...

  • Java基本算法——二分查找算法

    二分查找算法 每次查找取数组中位数的值进行比较,如果目标值值大于中位数的值,则截取中位数右侧的数组再次进行二分查找...

  • LintCode 80 [Median]

    原题 给定一个未排序的整数数组,找到其中位数。中位数是排序后数组的中间值,如果数组的个数是偶数个,则返回排序后数组...

  • 中位数

    给定一个未排序的整数数组,找到其中位数。中位数是排序后数组的中间值,如果数组的个数是偶数个,则返回排序后数组的第N...

  • OJ lintcode 中位数

    给定一个未排序的整数数组,找到其中位数。中位数是排序后数组的中间值,如果数组的个数是偶数个,则返回排序后数组的第N...

  • LeetCode题解4:Median of Two Sorted

    Median of Two Sorted Arrays问题:求2个有序数组的中位数,要求算法时间复杂度为O(log...

  • 数组中的值重复出现的次数

    问题描述:计算数组的值重复出现的次数 使用Map去统计,key值为数组中的值,value为值出现的次数。 输出结果...

  • 8、NumPy读写文件和基本函数

    均值(加权)、最大、最小、极差、中位数、方差、相邻元素差值、平方根、最大值的索引值、最小值的索引值、【所有数组中第...

  • Codeforces 1349B - Orac and Medi

    日常一道算法题。 翻译 有一个长度为 n 的整数数组 a。 每次操作可以选择一个子序列,让子序列的值变成中位数的值...

网友评论

      本文标题:凑数使数组中位数为特定值问题

      本文链接:https://www.haomeiwen.com/subject/koqegrtx.html