问题描述
小F手里有一个长度为nn的数组,他可以选择删除数组中的任意两个元素,并将它们的和作为一个新元素放回数组中。他最多可以进行一次这样的操作。小F的目标是使得数组的极值(即数组最大值减去最小值)尽可能小。现在你需要帮助小F计算出在最优操作下,数组能达到的最小极值。
测试样例
样例1:
输入:
n = 7 ,a = [1, 4, 3, 3, 2, 2, 3]
输出:2
样例2:
输入:
n = 5 ,a = [10, 5, 6, 7, 3]
输出:4
样例3:
输入:
n = 4 ,a = [1, 1, 1, 1]
输出:0
问题描述优化
小F手中有一个长度为 n 的数组,他可以选择删除数组中的任意两个元素,并将它们的和作为一个新元素放回数组中。目标是使得数组的极值(即数组最大值减去最小值)尽可能小。我们需要分析在最优操作下,数组能达到的最小极值。
情况一:数组中不存在负数
在这种情况下,我们不能通过删除和合并操作来减小最大值。因此,我们只能通过选择最小的两个值相加,尽可能提高最小值。具体步骤如下:
- 寻找最小值:找到数组中最小的两个值 a 和 b。
- 计算新元素:将这两个最小值相加得到新元素 c = a + b。
- 新数组极值计算:
- 新数组的最小值为 max(c, 第三小的值)。
- 新数组的最大值为 max(原最大值, c)。
- 比较极值差:计算新数组的极值差(新最大值 - 新最小值),并与未进行操作前的极值差进行比较,取较小值作为最终结果。
情况二:数组中存在负数
当数组中有负数时,我们可以通过合并负数和正数来有效减小极值。具体处理方式如下:
- 寻找关键值:遍历数组,找到最大的两个值(max1, max2)和最小的三个值(min1, min2, min3)。
- 新元素计算:
- 选择 min1 和 max1 进行相加,得到新元素 c = min1 + max1。
- 新数组极值计算:
- 新数组的最小值为 min(min2, c)。
- 新数组的最大值为 max(max2, c)。
- 比较极值差:计算新数组的极值差,并与未进行操作前的极值差进行比较,取较小值作为最终结果。
特殊情况处理
题目中强调最多进行一次操作,也就是说可以选择不进行任何操作。在这种情况下,我们需要预先记录未进行操作前的极值差,以便在后续比较中得到最终的最小极值差。
总结
通过上述分析,我们能够有效地计算出在一次操作后,数组可能达到的最小极值。无论是针对非负数的情况,还是存在负数的情况,我们都能找到合适的策略来优化极值差。
代码呈现
#include <iostream>
#include <vector>
#include <string>
#include <climits>
using namespace std;
int solution(int n, vector<int> a) {
// write code here
if(n==1) return 0;
int maxNum = INT_MIN,secMaxNum=INT_MAX;
int minNum = INT_MAX;
int secMinNum = INT_MAX,thirdMinNum=INT_MAX;
for(int i=0;i<a.size();++i){
if(a[i]>=maxNum) {
secMaxNum = maxNum;
maxNum = a[i];
}
else if(a[i]>secMaxNum){
secMaxNum = a[i];
}
if(a[i]<=minNum){
thirdMinNum = secMinNum;
secMinNum = minNum;
minNum = a[i];
}
else if(a[i]<=secMinNum){
thirdMinNum = secMinNum;
secMinNum = a[i];
}
else if(a[i]<thirdMinNum){
thirdMinNum = a[i];
}
}
int newNum = 0;
int initDiff = maxNum-minNum;
if(minNum<0){
newNum = minNum+maxNum;
maxNum = max(secMaxNum,newNum);
minNum = min(secMinNum,newNum);
}
else{
newNum = minNum+secMinNum;
maxNum = max(maxNum,newNum);
minNum= min(thirdMinNum,newNum);
}
return min(maxNum-minNum,initDiff);
}
int main() {
cout << (solution(7, {1, 4, 3, 3, 2, 2, 3}) == 2) << endl;
cout << (solution(5, {10, 5, 6, 7, 3}) == 4) << endl;
cout << (solution(4, {1, 1, 1, 1}) == 0) << endl;
return 0;
}