統計數組中差最小(或最大)的組合可能個數

騰訊2017暑期實習生編程題第三題

小Q今天在上廁所時想到了這個問題:有n個數,兩兩組成二元組,差最小的有多少對呢?差最大呢?

輸入例子:
6
45 12 45 32 5 6

輸出例子:
1 2

思路:先排序,分一般情況和特殊情況,

特殊情況數組所有元素相同,差最小最大的組合個數都是C(n,2)

否則,差最大的組合個數 = 最小值個數MinNum * 最大值個數MaxNum

接下來求 ,差最小(minVal )的組合個數,

(1)若最小差爲0,那麼統計不同的重複元素的個數,我這裏寫的roo是後面出現相同元素的個數,所以roo=1的意思是後續數組只有1個與當前值相同的元素,就是C(2,2),通用公式是C(roo+1,2)

(2)最小差不爲0,那麼用 map 統計後續數組與當前值能構成最小差的元素的個數roo,直接加

//O(n+nlogn)
#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <algorithm>
#include <map>
using namespace std;
const int maxn = 100050;
typedef long long int ll;
int a[maxn];
map<int,int> ma;
int main()
{   
//  freopen("in.txt",stdin,"r");
//  freopen("out.txt",stdout,"w");
    int n;
    while(scanf("%d",&n)!=EOF)
    {
        ma.clear();

        for(int i=0;i<n;++i)scanf("%d",&a[i]);
        sort(a,a+n);

        if(a[0] == a[n-1]){
            ll ans = n;
            if(ans > 1)ans = ans * (ans-1)/2;
            else ans = 0;// n == 1
            printf("%lld %lld\n",ans,ans);
        }
        else{
            ll MinNum = 0,MaxNum = 1,minVal = 2e11;

            for(int i = 0;i < n - 1;++i)
            {
                if(a[i]==a[0])MinNum++;
                if(a[i]==a[n-1])MaxNum++;
                if(minVal > a[i+1]-a[i]) minVal = a[i+1] - a[i];
                ma[a[i]]++;
            }

            ll MinAns = 0,roo = 0;

            if(minVal == 0){
                for(int i=0;i<n-1;++i)
                {
                    if(a[i]==a[i+1])roo++;
                    else {
                        if(roo>0){
                            MinAns = MinAns + roo * (roo+1) / 2;
                            roo = 0;
                        }                       
                    }
                }
                if(roo>0){
                    MinAns = MinAns + roo * (roo+1) / 2;
                    roo = 0;
                }       
            }   
            else {
                for(int i = 0;i < n;++i){
                    roo = ma[a[i]+(int)minVal];
                    if(roo > 0) MinAns += roo;
                }   
            }               

            printf("%lld %lld\n",MinAns,MinNum * MaxNum);
        }       
    }
    return 0;
} 
發佈了39 篇原創文章 · 獲贊 15 · 訪問量 4萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章