牛客网模拟测试 3 道编程题

第一题

题目链接
给定 n 个整数,将 n 个整数排成一圈,首位相邻,求出所有排列中相邻的数的最大差的最小值
例如:98 100 103 105 四个数,排列成 98 103 105 100 这个排列,最大差是 5,是所有可能的排列中最大差最小的

对于已经排序好的数列 1 3 7 8 10 来说,我们从 2 个数开始排列,然后依次插入数列中的下一个数
首先 对于 1 3 而言,下面在 1 3 中插入 7 ,很显然要把 7 插入 1 和 3 中间,得到 1 7 3 这样才能满足最大差最小,那么下一个 8 应该插在什么地方呢,应该是 7 和 3 之间,得到 1 7 8 3,同样 10 应该插入 7 和 8 之间,得到 1 7 10 8 3。
假设对于一个排序好的数列,对于数列的前 k 个数,我们通过某种排列使得最大差最小,发现原数列中的第 k 个数 和 k - 1 个数总是相邻的,而且对第 k + 1 个数来说,总是将它插入第 k 个数和第 k - 1 个数之间,记前 k 个数的最大差的最小值为 f(k),那么 k + 1 个数的最大差的最小值为 max(f(k), a[k+1] - a[k-1]),对 k 从 3 开始,可以得到实际上是求 max(a[k] - a[k-2])
关键的代码如下

int max = 0;
for(int i = 2; i < n; i++) {
    if(a[i] - a[i-2] > max) max = a[i] - a[i-2]; 
}

按照上述的分析,其实可以构造出来这样的序列,那么这是一个什么样的序列呢?

其实我自己最初的想法是对于一个排序好的数组,按照下标奇偶将数组分成两部分,第一部分从前往后,第二部分从后往前将数据填入新的数组中,这样就构造出了满足最大差最小的排列
例如对数列 1 3 7 8 10 11 15,分成两部分分别是 1 7 10 15 和 3 8 11,然后分别填入新的数组
这里写图片描述
最后得到 1 7 10 15 11 8 3,计算这个数列的最大差即可
代码如下

public class Mo1 {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int N = sc.nextInt();
        int[] height = new int[N];
        for (int i = 0; i < N; i++) {
            height[i] = sc.nextInt();
        }

        Arrays.sort(height);

        int[] re = new int[N];

        int i = 0, j = N-1;
        for (int ptr = 0; ptr < N; ptr+=2) {
            re[i++] = height[ptr];
            if (ptr + 1 < N)
                re[j--] = height[ptr+1];
        }
        int max = 0;
        for (int p = 0; p < N; p++) {
            if (p == N-1) {
                if (Math.abs(re[p] - re[0]) > max)
                    max = Math.abs(re[p] - re[0]);
            } else {
                if (Math.abs(re[p] - re[p+1]) > max)
                    max = Math.abs(re[p] - re[p+1]);
            }
        }
        System.out.println(max);
    }
}

第二题

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值