Leetcode:334. 递增的三元子序列

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

数学表达式如下:

如果存在这样的  i, j, k,  且满足 0 ≤  i <  j <  k ≤  n-1,
使得  arr[i] <  arr[j] <  arr[k] ,返回 true ; 否则返回 false 。

说明: 要求算法的时间复杂度为 O(n),空间复杂度为 O(1) 。

示例 1:

输入: [1,2,3,4,5]
输出: true

示例 2:

输入: [5,4,3,2,1]
输出: false

解题思路:

逻辑题。

  1. 找到一个递增数num[pos],例如,[5,4,3,4,5,6,]中第4个数4就是第一个递增数。
  2. 第一个递增数的前面必然是当前遇到的最小数。如果不是那么nums[pos-1]才是第一个递增数。如果连递增数都没有,就不可能有三连递增。
  3. 这里我们确定了二元递增的两个数,nums[left],nums[right],其中left=pos-1,right=pos。以及最小数的位置temp,一开始nums[temp]=nums[pos-1]。
  4. 随后接着访问pos+1,nums[pos+1]需要根据数值de得大小分类处理。
  • nums[pos+1]>nums[right],那么找到了三元序列。
  • nums[pos+1]>nums[left]&&nums[pos+1]<=nums[right]。修改二元序列得右值,right = pos+1;
  • nums[pos+1]<=nums[temp]。修改位于left之后最小数得位置。temp=pos+1。
  • nums[pos+1]>nums[temp]&&nums[pos+1]<=nums[left],说明,发现了位置跟后,数值更小得得二元序列,二元序列需要改变位置。left = temp,right=pos+1。

重复上述步骤直到访问所有元素。

C++代码
class Solution {
public:
    bool increasingTriplet(vector<int>& nums) {
        int size = nums.size();
        //找到第一个升序
        int i = 0, pos = -1, min = INT_MAX;
        while (i < size-1) {
            if (nums[i] < nums[i + 1]) { pos = i; break; }
            min = (nums[i] < min ? nums[i] : min);
            i++;
        }
        if (pos == -1) return false;
        int left = i, right = i + 1;
        pos = right + 1;
        int temp = left;
        while (pos < size) {
            if (nums[pos]>nums[right]) return true;
            if (nums[pos] <= nums[temp]) temp = pos;
            if (nums[pos] > nums[temp] && nums[pos] <= nums[left]) { left = temp; right = pos; }
            if (nums[pos] >nums[left] && nums[pos] <= nums[right]) right = pos;
            pos++;
        }
        return false;
    }
};

猜你喜欢

转载自blog.csdn.net/qq_23523409/article/details/84674001