湊數使數組中位數為特定值問題

題目描述:
小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) {//前面是相等退出,所以如果前面循環(huán)執(zhí)行了,后面的就不會執(zhí)行
            nums.add(100000);//用最大可能的值100000,或者用nums[nums.size()-1],保證數組仍然有序
            ans++;
        }
        //直接滿足nums.get((nums.size()-1)/2) == x的話,前面兩個循環(huán)就都不會走
        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的時候也適配此規(guī)則)
            //依照最少增加原則,使得增加后,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的時候也適配此規(guī)則)
            //依照最少增加原則,使得增加后,EL左邊的數字數比右邊數字數少一個即可(數組總個數為偶數時,中位數左邊比右邊少一個數)
            //所以增加個數=(EL當前右邊的數字數-1)-E0當前左邊的數字數=greater-1-(less+equal-1)
            System.out.println(greater-1-(less+equal-1));
        }
    }
}
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

友情鏈接更多精彩內容