最大差值和最小差值数对问题--腾讯笔试

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
/*
问题描述:
小Q今天在上厕所时想到了这个问题:有n个数,两两组成二元组,差的绝对值最小的有多少对呢?差的绝对值最大的呢?
输入描述:
输入包含多组测试数据。
对于每组测试数据:
N - 本组测试数据有n个数(n>= 2)
a1,a2…an - 需要计算的数据
保证:
1<=N<=100000,0<=ai<=INT_MAX.


输出描述:
对于每组数据,输出两个数,第一个数表示差的绝对值最小的对数,第二个数表示差的绝对值最大的对数。
输入例子:
6
45 12 45 32 5 6
输出例子:
1 2
*/
int main()
{
    int N;
    while(scanf("%d", &N)!= EOF)
    {
        int i, l, min, max, min_count = 0, max_count = 0;
        int * array;
        array = (int *)malloc(sizeof(int)*N);
        for(i = 0; i < N; i++)
            scanf("%d", &array[i]);
        min = array[N-1] - array[N-2];
        max = array[N-1] - array[N-2];//初始化最大差值和最小差值为数组最后两个元素的差值
        for(l = 1; l < N; l++)//设置滑动条的长度
        {
            for(i  = 0; i < N-l; i++)
            {
                if(abs(array[i]-array[i+l]) == min) min_count++;//两元素差值与当前最小差值相等,最小差值数自增
                else if(abs(array[i]-array[i+l]) > min) goto LOOP;//两元素差值比当前最小差值大,跳转
                else//两元素差值比当前最小差值大,将最小差值数置为1,从新计数,最小差值更新
                {
                    min_count = 1;
                    min = abs(array[i]-array[i+l]);
                }
            LOOP:
                if(abs(array[i]-array[i+l]) == max) max_count++;//原理同上
                else if(abs(array[i]-array[i+l]) < max) continue;
                else
                {
                    max_count = 1;
                    max = abs(array[i]-array[i+l]);
                }


            }
        }
        printf("%d %d\n", min_count, max_count);
        free(array);
    }
    return 0;

}

/*优化思路:
首先使用快排将数组从小到大排列,便于统计数对数量,时间复杂度降为快排的时间复杂度O(NlgN)

int cmp(const void *a, const void *b)
{
    return *(int *)a-*(int *)b;//从小到大排序
}

int main()
{
    int N;
    while(scanf("%d", &N)!= EOF)
    {
        int i;
        int min, max;
        int min_count = 0, max_result = 0, min_result = 0;
        int * array;
        array = (int *)malloc(sizeof(int)*N);
        for(i = 0; i < N; i++)
            scanf("%d", &array[i]);
        qsort(array, N, sizeof(array[0]), cmp);//快排
        min = array[1]-array[0];//最小差值为1号元素和0号元素的差值
        max = array[N-1]-array[0];
        for(i = 0; i < N-1; i++)
        {
            if(array[i] == array[0]) min_result++;
            if(array[i+1] == array[N-1]) max_result++;//统计最小元素和最大元素的个数,最大数对即是两者之积
            if((array[i+1]-array[i]) == min) min_count++;//统计最小数对的个数
        }
        if(!min)//当最小差值为0时
            min_count = min_count*(min_count+1)/2;//组合问题,(min_count+1)个相同元素中选两个元素组合,注意:min_count为最小数对的个数不是相同元素的个数
        if(max)//当最大差值不为0时
            printf("%d %d\n", min_count, min_result*max_result);
        else printf("%d %d\n", min_count, min_count);//最大差值为0,最小差值数对就是最大差值数对
        free(array);
    }
    return 0;

参考文章:https://blog.csdn.net/woshidahuaidan2011/article/details/51987068

*/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值