LeetCode 334. Increasing Triplet Subsequence

来源:互联网 发布:如何查看淘宝客佣金 编辑:程序博客网 时间:2024/05/24 05:41

Description:
Given an unsorted array return whether an increasing subsequence of length 3 exists or not in the array.

Formally the function should:
Return true if there exists i, j, k
such that arr[i] < arr[j] < arr[k] given 0 ≤ i < j < k ≤ n-1 else return false.
Your algorithm should run in O(n) time complexity and O(1) space complexity.

Examples:
Given [1, 2, 3, 4, 5],
return true.

Given [5, 4, 3, 2, 1],
return false.

本题要求在一个无序数组中找到一对呈升序排列的三元组,题目的难点在于要求时间复杂度为O(n),所以就要求在一次遍历中找到符合要求的三元组了。
我的想法是,要找到这样的一对三元组,那么首先先找到一对升序的二元组,然后在接下来的遍历中如果找到了一个比这个二元组的两个数都大的数,那就完成查找了。
不过,显然这个二元组是要随着遍历的进行根据某些条件而改变的,我们用两个变量,c1和c2分别表示该二元组中较小的数和较大的数。那么在遍历的过程中,如果发现了一个比c1小的数,那么我们认为在这个数之后,可能存在整体比当前的c1和c2更小的一个二元组x1,x2(即x1 < c1 && x2 < c2 && x2 > c1),那么我们将c1设置为x1。
不过此处要注意,由于c2还没有遇到一个比他小且大于c1的数,所以我们认为当前的二元组并没有改变,仍然是c1和c2的组合,虽然c1的值改变了。只有在之后的遍历中遇到了满足上述条件的x2,我们才能将c2设置为x2。此时二元组的值才能算是从(c1,c2)变为了(x1,x2)。
接着简单地说明一下上述算法的合理性:在任意时刻,c1和c2代表的是一个呈升序排列的二元组,同时c1的值在原数组中的位置一定是在c2之前的。这里的位置在c2之前是一个抽象的概念,因为在上文中我们提到c1可能会被设置为一个在c2之后但小于c1的数x1。但是由于我们强调了二元组的改变是要c2改变了之后才会改变的,所以即使c1改变了,只要c2还没有被设置为一个更小的数,那么此处存在的二元组还是满足下标和大小都是呈升序排列的。举个例子:
[2,5,4,1,6],在这个数组中,在遍历了前三个数之后,此时的二元组(c1,c2)是(2,4),接下来遍历到1的时候,c1被设置为了1且c1在数组中的位置在c2之后了,然而由于c2没有改变,所以在概念上二元组的值仍是(2,4)
代码如下:

class Solution {public:    bool increasingTriplet(vector<int>& nums) {        int c1 = INT_MAX, c2 = INT_MAX;        for(int x: nums) {            if(x <= c1)                c1 = x;            else if(x <= c2)                c2 = x;            else                return true;        }        return false;    }};
原创粉丝点击