给你一个下标从 0 开始的整数数组 nums ,该数组的大小为 n ,请你计算 nums[j] - nums[i] 能求得的 最大差值 ,其中 0 <= i < j < n 且 nums[i] < nums[j] 。
返回 最大差值 。如果不存在满足要求的 i 和 j ,返回 -1 。
示例输入:nums = [7,1,5,4] 输出:4 解释: 最大差值出现在 i = 1 且 j = 2 时,nums[j] - nums[i] = 5 - 1 = 4 。 注意,尽管 i = 1 且 j = 0 时 ,nums[j] - nums[i] = 7 - 1 = 6 > 4 ,但 i > j 不满足题面要求,所以 6 不是有效的答案。 输入:nums = [9,4,3,2] 输出:-1 解释: 不存在同时满足 i < j 和 nums[i] < nums[j] 这两个条件的 i, j 组合。 输入:nums = [1,5,2,10] 输出:9 解释: 最大差值出现在 i = 0 且 j = 3 时,nums[j] - nums[i] = 10 - 1 = 9 。解法一:暴力法
最直接简单的解决方案当然是暴力,因此先考虑暴力实现并观察效果。具体实现代码如下
class Solution {
public int maximumDifference(int[] nums) {
return brust(nums);
}
//暴力解法
public int brust(int[] nums){
int size = nums.length;
int ans = 0;
//双重循环,保证j>i,并不断计算更新其最大差值
for(int i = 0;i < size;++i){
for(int j = i + 1;j < size;++j){
//使用三目运算符找较大值,并实现更新
ans = ans > (nums[j] - nums[i])?ans:nums[j] - nums[i];
}
}
//判断ans是否发生变化(或者计算后最大差值是0不满足条件),若不存在递增序列,返回-1
return ans == 0 ? -1:ans;
}
}
其执行效果如下所示
54 / 54 个通过测试用例 状态:通过 执行用时: 3 ms 内存消耗: 40.3 MB 提交时间:27 分钟前
时间复杂度为O(n2)。可以看见虽然代码确实可行,但时间复杂度较高,因此考虑能否对算法进行优化。
解法二:最小前缀考虑能否对算法时间复杂度优化到O(n)范围内。分析数组,若存在nums[j] < nums[i],且j > i,则应更新其最小前缀(若存在k,有nums[k] > nums[i] > nums[j],且k > j > i,则ans = nums[k] - nums[i])。若不存在nums[j] < nums[i],且j > i,则nums[i] 是当前遍历的数组范围内([0,j])最小值,不需更新。其具体实现代码如下:
class Solution {
public int maximumDifference(int[] nums) {
return minPrefix(nums);
}
public int minPrefix(int[] nums){
int min = nums[0],max = -1;
int size = nums.length;
int ans = 0;
for(int i = 0;i < size;++i){
if(min > nums[i]){
min = nums[i];
max = nums[i];
}
if(max < nums[i]){
max = nums[i];
ans = ans > max - min? ans:max - min;
}
}
return ans == 0 ? -1 : ans;
}
}
其执行效果如下:
54 / 54 个通过测试用例 状态:通过 执行用时: 0 ms 内存消耗: 40.6 MB 提交时间:29 分钟前
算法时间复杂度为O(n)。



