算法训练-力扣.334递增的三元子序列(贪心)

题目描述

给你一个整数数组 nums ,判断这个数组中是否存在长度为 3 的递增子序列。

如果存在这样的三元组下标 (i, j, k) 且满足 i < j < k ,使得 nums[i] < nums[j] < nums[k] ,返回 true ;否则,返回 false 。

示例 1:

输入:nums = [1,2,3,4,5]
输出:true
解释:任何 i < j < k 的三元组都满足题意

示例 2:

输入:nums = [5,4,3,2,1]
输出:false
解释:不存在满足题意的三元组

示例 3:

输入:nums = [2,1,5,0,4,6]
输出:true
解释:三元组 (3, 4, 5) 满足题意,因为 nums[3] == 0 < nums[4] == 4 < nums[5] == 6

提示:

  • 1 <= nums.length <= 5 * 105
  • -231 <= nums[i] <= 2^{31} - 1

解题

题解①:贪心

根据题意我们要找到满足这些条件的情况: i < j < k ,使得 nums[i] < nums[j] < nums[k]

那我们不妨将这题换一种问法,将nums[i]和nums[j]看成一组,在这一组中,确保i < j并且nums[i]<nums[j]即可,现在我们需要找出一个数nums[k]大于这个组也就是大于nums[j],同时还要保证k > j。这么一说,咋一看感觉跟原题目并没区别,为什么要单独将前两个数划为一组呢?不急,我们接着往下看。

拿上面的实例3举例:将实例3的数组[2,1,5,0,4,6]用图表示出来:

也容易得知,其中三元组(3,4,5)、(0,1,4)...等等都是满足题意 i<j<k且nums[i]<nums[j]<nums[k]的,

为了方便观看我们用不同颜色的线标出来

三元组为(3,4,5)的情况:                                三元组为(0,1,4)的情况:

画这个图是为了更直观地发现我们该如何解决这个问题,到这里我们应该就有很清晰的解题思路了:

①确保绿线也就是nums[k]必须在橙线nums[j]上方,也就是nums[k]>nums[j],只要找到符合这个条件的绿线,也就是找到一种nums[k] > nums[j]的情况,那么答案也就出来了。

②那我们怎样才能更大概率或者说更好地找到这种组合呢?那肯定是让橙线越低越好,也就是nums[j]越小越好。因为nums[j]越小,满足j < k且nums[j] < nums[k]条件的k才越多。

③那橙线能无限低也就是nums[j]能无限小吗?肯定是不能的,约束nums[j]的就是nums[i]。

所以,我们要做的是,定义两个数,a和b(对应着红线和橙线),遍历数组:for(int i = 0;i < nums.length;++i)。确保a永远是nums[0] ~ nums[i]中最小的值,确保b永远是在 ( a,nums[i] ]区间内最小的一个。当遍历到 nums[i] > nums[j]即可以返回true,遍历完还没找到就返回false。

不难得出下面代码:

    public boolean increasingTriplet(int[] nums) {
        if (nums.length < 3)
            return false;
        int a = nums[0];
        int b = Integer.MAX_VALUE;
        for (int i = 1;i < nums.length;++i){
            int num = nums[i];
            if (num > b){
                return true;
            } else if (num > a){
                b = num;
            } else {
                a = num;
            }

        }
        return false;
    }

所以,这种解法我们可以发现,它贪心是贪在nums[i]和nums[j]尽量小这方面。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值