避免 (双层循环的暴力解法)
概要
-通常情况下,在做简单题或中等题时为了缩短思考时间,在数组问题中,但涉及到子元素,最大差值,最大和等问题时,我们习惯用前缀和,双指针等暴力解法来解决问题;
-但是,这有一半的几率会出现超时情况,因为一般双指针暴力解法的时间复杂度都在O(n^2)以上;
-本文章将采用O(n)的时间复杂度解决类似问题
例一 数组美丽值求和
给你一个下标从 0 开始的整数数组 nums 。对于每个下标 i(1 <= i <= nums.length - 2),nums[i] 的 美丽值 等于:
2,对于所有 0 <= j < i 且 i < k <= nums.length - 1 ,满足 nums[j] < nums[i] < nums[k]
1,如果满足 nums[i - 1] < nums[i] < nums[i + 1] ,且不满足前面的条件
0,如果上述条件全部不满足
返回符合 1 <= i <= nums.length - 2 的所有 nums[i] 的 美丽值的总和 。
示例 1:
输入:nums = [1,2,3]
输出:2
解释:对于每个符合范围 1 <= i <= 1 的下标 i :
- nums[1] 的美丽值等于 2
示例 2:
输入:nums = [2,4,6,4]
输出:1
解释:对于每个符合范围 1 <= i <= 2 的下标 i :
- nums[1] 的美丽值等于 1
- nums[2] 的美丽值等于 0
示例 3:
输入:nums = [3,2,1]
输出:0
解释:对于每个符合范围 1 <= i <= 1 的下标 i :
- nums[1] 的美丽值等于 0
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/sum-of-beauty-in-the-array
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
代码
前序遍历&&后序遍历
class Solution {
public int sumOfBeauties(int[] nums) {
int n = nums.length;
boolean[] tmp = new boolean[n];
int max = nums[0];
int min = nums[n-1];
int ans = 0;
for(int i = 1;i<=n-2;i++){
if(nums[i] > max){
max = nums[i];
tmp[i] = true;
}
}
for(int i = n-2;i>=1;i--){
if(nums[i] < min){
min = nums[i];
}else{
tmp[i] = false;
}
}
for(int i = 1;i<=n-2;i++){
if(tmp[i]){
ans += 2;
}else if(nums[i] > nums[i-1] && nums[i] < nums[i+1]){
ans += 1;
}
}
return ans;
}
}
详解
-
1.如果用双指针暴力解法,需要至少两层for循环
-
2.为了节省时间,注意:因为该题的要点还是比较大小;因为比较大小,所以一定与数组中的最大值和最小值有关,我们只需要根据提议,设置max或min或max&min来分别记录当前比较状态下的最大最小值,则可以用比较省去额外的for循环;
例二 增量元素之间的最大差值
给你一个下标从 0 开始的整数数组 nums ,该数组的大小为 n ,请你计算 nums[j] - nums[i] 能求得的 最大差值 ,其中 0 <= i < j < n 且 nums[i] < nums[j] 。
返回 最大差值 。如果不存在满足要求的 i 和 j ,返回 -1 。
示例 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 不是有效的答案。
示例 2:
输入:nums = [9,4,3,2]
输出:-1
解释:
不存在同时满足 i < j 和 nums[i] < nums[j] 这两个条件的 i, j 组合。
示例 3:
输入:nums = [1,5,2,10]
输出:9
解释:
最大差值出现在 i = 0 且 j = 3 时,nums[j] - nums[i] = 10 - 1 = 9 。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/maximum-difference-between-increasing-elements
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
代码
class Solution {
public int maximumDifference(int[] nums) {
int left=0;
int right=1;
int max=-1;
while(right<nums.length){
if(nums[left]<nums[right]){
max = Math.max(max,nums[right]-nums[left]);
}else{
left=right;
}
right++;
}
return max;
}
}
详解
1.幸运的是在周赛的时候因为着急做题,直接暴力,没有超出时间限制直接AC了,但该题是用双指针仍然需要O(n^2)的时间复杂度
2.后期发现该题依旧可以使用max来实时更新最大值的状态,用比较代替一层for循环
总结
遇到可以用双指针暴力解的题目,特别涉及到比较、最大差值、最小和值等一些列问题时,可以优先考虑使用max,min来实时保存当前状态,降低时间复杂度,降低超出时间限制的概率。
作者:ELE(ele)
链接:https://leetcode-cn.com/problems/maximum-subarray/solution/qian-zhui-he-java-by-objective-volhardsh-ja05/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。