题目背景
小M有一个数组,她可以执行一次操作:选择两个相邻的元素并将它们合并,合并后的新元素值为原来两个元素的和。合并操作之后,数组的长度将减少1。小M想知道,执行一次操作后,数组的极差(最大值减去最小值)的最小可能值是多少。
测试样例
样例1:
输入:
n = 3 ,a = [1, 4, 5]
输出:0
样例2:
输入:
n = 5 ,a = [3, 6, 2, 8, 7]
输出:5
样例3:
输入:
n = 4 ,a = [10, 20, 30, 40]
输出:10
思路
-
遍历所有可能的合并操作:
- 对于数组中的每一对相邻元素,计算合并后的新数组。
- 计算新数组的极差。
-
选择极差最小的合并操作:
- 记录所有合并操作后的极差,选择最小的那个。
数据结构选择
- 使用数组来存储原始数组和合并后的数组。
- 使用变量来记录最小极差。
算法步骤
-
初始化一个变量
min_range为一个大数(例如INT_MAX)。 -
遍历数组中的每一对相邻元素:
- 计算合并后的新数组。
- 计算新数组的极差。
- 更新
min_range为当前极差和min_range中的较小值。
-
返回
min_range。
通过这种方式,可以找到执行一次合并操作后,数组的极差的最小可能值。
题解代码
int solution(int n, vector<int> a) {
// 初始化最小极差为一个很大的数
int min_range = 1000000;
// 遍历数组中的每一对相邻元素
for (int i = 0; i < n - 1; ++i) {
// 计算合并后的新数组
vector<int> new_array = a;
new_array[i] = new_array[i] + new_array[i + 1];
new_array.erase(new_array.begin() + i + 1); // 删除合并后的元素
// 计算新数组的极差
int max_val = *max_element(new_array.begin(), new_array.end());
int min_val = *min_element(new_array.begin(), new_array.end());
int current_range = max_val - min_val;
// 更新最小极差
min_range = min(min_range, current_range);
}
return min_range;
}
步骤解释
- 初始化最小极差:使用
INT_MAX初始化min_range,确保任何极差都会比它小。 - 遍历相邻元素:使用
for循环遍历数组中的每一对相邻元素。 - 合并操作:将相邻的两个元素合并,并更新数组。
- 计算极差:使用
max_element和min_element函数计算新数组的最大值和最小值,然后计算极差。 - 更新最小极差:使用
min函数更新min_range。
优化思路
- 避免创建新数组:可以直接在原数组上进行操作,而不需要创建新的数组。
- 减少不必要的操作:在计算极差时,可以直接使用原数组的最大值和最小值,而不需要每次都重新计算。