递增的三元子序列+进阶+实现

题目:
在这里插入图片描述
常规思考:

  1. 既然是长度为3的递增子序列,定义为《a,b,c》那么对于每一个可能的数组中的数字进行判断,如果作为b且存在能找到的a和c就说明存在这样的子序列(之所以 以作为b来判断是为了方便实现)
  2. 使用动态规划
  3. 两个数组分别遍历后记录下nums中在每个数组左边(前缀)的最小值 和 在右边的(后缀)最大值
  4. 之后再次遍历nums,如果找到一个数字x,并且左边(前缀)的最小值 <x且在右边的(后缀)最大值>x那么就存在这样的递增子序列

实现:

class Solution {
public:
    bool increasingTriplet(vector<int>& nums) {
        vector<int> min_left(nums.size(),INT_MAX);
        vector<int> max_right(nums.size(),INT_MIN);

        bool ret=false;
        
        min_left[0]=nums[0];
        for (int i=1;i<nums.size();i++)
        {
            min_left[i]=min(min_left[i-1],nums[i]);
        }
        max_right[nums.size()-1]=nums.back();
        for (int i=nums.size()-2;i>-1;--i)
        {
            max_right[i]=max(max_right[i+1],nums[i]);
        }


        for (int i=0;i<nums.size();++i)
        {
            if (nums[i]>min_left[i]&&nums[i]<max_right[i])
            {
                ret=true;
                break;
            }
        }


        return ret;
    }
};

进阶思考:

  1. 如果必须要常数空间复杂度那么常规思路中的使用数组记录最大最小值就不能使用了
  2. 使用《nums[0],max.max》作为初始三元组记为《a,b,c》(当然这个不能作为所谓的子序列)
  3. 遍历nums(1-----(n-1)),对于每一个遍历到的数字,判断如果大于b说明找到了这样的递增子序列,不过小于b且大于a,那么更新b的值,如果小于a,更新a的值
  4. 也许有朋友有疑问在于如果小于a,更新a的值 这里,记录更新后的a为a1:《a1,b,c》中a1的位置在b之后怎么能作为递增三元组嘞?
    1. 更新后的a为a1:《a1,b,c》,如果b和c不是max的话说明存在题目要求的三元组,因为存在的三元组不是指《a1,b,c》,而是指《a,b,c》
    2. 举个例子:4,5,3,6
    3. 初始<4,max,max> -> <4,5,max> -> < 3,5,max> --> < 3,5,6>(找到)
    4. 最终的三元组<3,5,6>并不是符合要求的三元组,<4,5,6>才是
    5. 这个例子是为说明如果存在《a1,b,c》满足条件则《a,b,c》一定满足条件,也就是说,替换a不会导致存不存在那样的三元组的回答更改
    6. 那么为什么要更新a值呐?
      1. 我们当然希望a最小,更有希望找到大于a的b,同理a小找到的b也就更小,更有可能找到符合条件的c
      2. 举个例子:4,5,1,2,3
      3. 初始<4,max,max> -> <4,5,max> -> <1,5,max> -> <1,2,max> -> <1,2,3>(找到)

实现:

class Solution {
public:
    bool increasingTriplet(vector<int>& nums) {
        if (nums.size()<3)  return false;
        int l=nums[0];
        int m=INT_MAX;

        bool ret=false;
        for (int i=1;i<nums.size();i++)
        {
            if(nums[i]>m)
            {
                ret-=true;
                break;
            }
            else if (nums[i]>l)
            {
                m=nums[i];
            }
            else
            {
                l=nums[i];
            }
        }


        return ret;
    }
};