2021-09-27-ELE 避免 (双层循环的暴力解法)

避免 (双层循环的暴力解法)

概要

-通常情况下,在做简单题或中等题时为了缩短思考时间,在数组问题中,但涉及到子元素,最大差值,最大和等问题时,我们习惯用前缀和,双指针等暴力解法来解决问题;

-但是,这有一半的几率会出现超时情况,因为一般双指针暴力解法的时间复杂度都在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)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值