334. 递增的三元子序列
难度中等464
给你一个整数数组 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] <= 231 - 1
进阶:你能实现时间复杂度为 O(n) ,空间复杂度为 O(1) 的解决方案吗?
思路一:实际上我们很容易就可以想到这是一个求最长上生子序列长度>=3的问题,然后直接套模板就ok~
class Solution { public: bool increasingTriplet(vector& nums) { int dp[5], cnt = 1, n = nums.size(), *p; dp[0] = nums[0]; for(int i = 1; i < n; ++ i){ p = lower_bound(dp, dp + cnt, nums[i]); if(p == dp + cnt){ ++ cnt; } *p = nums[i]; if(cnt >= 3)return true; } return false; } };
思路二:实际上我们即使用优化的最长上升子序列DP也只能做到O(nlgn),况且本题要求的长度大于3即可,是不是有点大材小用了。回过头来想,只要我们能找到一个长度为3的上升序列,那么本题就已经解了。假设我们现在考虑nums[j]是否能成为一个长度为3的子序列的中值,那么我们只需要找到一个i 再想一下,其实我们关系的是大小关系而不是数值,举例来说3 4 5,3和4都小于5,我们只关心5的左边是否有数小于5,而并不关心具体的数值是多少。同时,为了能够使得nums[i]可以成为中值,我们只需要考虑1~i-1上的最小值即可,右端同理。 因此我们定义两个数组left_min与right_max,维护左边的最小值和右边的最大值,那么只要找到一个i,有left_min[i] 思路三:此时我们不再去看一个数nums[i]是否能成为中值,而是考虑保存第一第二的值,来考虑第三个值。基于贪心策略,我们第一第二的值越小,可以构成长度为3的上升序列概率越大。 记第一个数为first,第二个数为second,算法流程如下 1.first=nums[0],second=0x7fffffff 2.遍历1~n-1位置的元素,按照如下方式更新 A.nums[i] > second,此时first、second、nums[i]就构成了我们需要的序列 B.nums[i] <= second && nums[i] > first,此时很显然我们可以将second变小(或不变),second变小,后面的数就更可能大于second,即构成长度为3的上升序列 C.nums[i] < first,这时候我们只要让first = nums[i],w h y ? 其实是这样的,我们可以考虑一个例子如下: 3 4 1 6 当我们遍历到1的时候,直觉告诉我们可以调小first,但我们是不可以把second=旧的first的,因为旧的first一定在当前位置i前面,这样赋值是不满足子序列的顺序要求的,这是第一点。第二点是,如果我们此时将second=0x7fffffff,那么我们会错过满足条件的序列3 4 6。也就是说我们用旧的second和新的first,就可以同时考虑两个序列。而这种机制也不会有问题,因为这种机制只是保证在second发生实质性的更新前可以考虑旧的first-second序列,对上例来说就是在遍历6的时候由于seance=4,其实还考虑的旧的序列3 4。 而当second发生更新,则说明在second未更新这段时间内,并没有能够与旧序列拼成长度为3的上升子序列的情况,例子如下: 3 4 0 0 0 1 如上例所示,在第二个0到第三个0时,second并未更新,然而这段区间上也找不到第三个位置的数,遍历到1的时候,second可以更新,此时对于1后面的数来说,考虑这个更小的second会更容易组成长度为3的上升序列。 欢迎分享,转载请注明来源:内存溢出class Solution {
public:
bool increasingTriplet(vector
class Solution {
public:
bool increasingTriplet(vector
评论列表(0条)