合并数组后的最大元素
难度:中等
题目描述
给你一个下标从 0 开始、由正整数组成的数组 nums
。
你可以在数组上执行下述操作 任意 次:
- 选中一个同时满足
0 <= i < nums.length - 1
和nums[i] <= nums[i + 1]
的整数i
。将元素nums[i + 1]
替换为nums[i] + nums[i + 1]
,并从数组中删除元素nums[i]
。
返回你可以从最终数组中获得的 最大 元素的值。
示例 1:
输入:nums = [2,3,7,9,3] 输出:21 解释:我们可以在数组上执行下述操作: - 选中 i = 0 ,得到数组 nums = [5,7,9,3] 。 - 选中 i = 1 ,得到数组 nums = [5,16,3] 。 - 选中 i = 0 ,得到数组 nums = [21,3] 。 最终数组中的最大元素是 21 。可以证明我们无法获得更大的元素。
示例 2:
输入:nums = [5,3,3] 输出:11 解释:我们可以在数组上执行下述操作: - 选中 i = 1 ,得到数组 nums = [5,6] 。 - 选中 i = 0 ,得到数组 nums = [11] 。 最终数组中只有一个元素,即 11 。
解题思路
先捋一下题意:输入一个数组,然后对数组中的相邻元素进行合并计算,合并后的结果替换掉原来的两个元素(满足合并计算的要求:1.相邻;2.前面的元素小于等于后面的元素)。一直执行这样的合并计算到整个数组没有满足合并计算要求的元素,最后输出当前数组中最大的元素。
现在来解题:还是贪心奥,要想合并出最大的元素,就要尽可能的多进行合并运算,让后面的元素尽可能的大。通常我们都是正向遍历,但是这次我们希望后面的元素越大越好,那么我们这次选择的就是倒序遍历。
- 逆向遍历数组
java
class Solution {
public long maxArrayValue(int[] nums) {
int temp = nums.length - 1;
int res = nums[temp];
for(int i = temp - 1; i >= 0; i--){
// 合并计算
}
return res;
}
}
- 合并计算
java
class Solution {
public long maxArrayValue(int[] nums) {
int temp = nums.length - 1;
long res = nums[temp];
for(int i = temp - 1; i >= 0; i--){
if(res >= nums[i]){
res += nums[i];
}else{
res = nums[i];
}
}
return res;
}
}
这道题到这里呢也就解出来了,个人感觉这道题倒是没有中等的难度,不过力扣官方给中等难度应该是有他的原因的。
这道题难点在于去理解合并计算的过程,我们可以把这个过程看成是大鱼吃小鱼的过程,并且限制了只能向左去吃,如果我们还是正向遍历的话,就会导致前面的鱼比较大,后面就没法吃出最大的鱼,我们现在来模拟一下过程看看区别。
数组:[1,2,4,5,6]
正向遍历:[1,2,4,5,6]->[3,4,5,6]->[7,5,6]->[7,11] 输出结果:11
逆向遍历:[1,2,4,5,6]->[1,2,4,11]->[1,2,15]->[1,17]->[18] 输出结果:18
这样大家应该就明白了。
代码分析
复杂度分析
- 时间复杂度:O(n)。
- 时间复杂度:O(1)。
其中 n 是数组的长度。
代码优化
又到了代码优化环节,代码优化可以是运行时间上的优化,也可以是代码简洁度上的优化,我们来尝试将代码写的更简洁。
java
class Solution {
public long maxArrayValue(int[] nums) {
long res = nums[nums.length - 1];
for(int i = nums.length - 2; i >= 0; i--) res = res >= nums[i] ? res + nums[i] : nums[i];
return res;
}
}