[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、第一种方法——最直接的思路

1)采用动态规划的方法,dp[i]代表以nums[i]为结尾的递增子序列长度
2)dp[i]=max{dp[j]+1},j<i&&nums[j]<nums[i]
3)时间复杂度为n*n

 1 class Solution {
 2 public:
 3     bool increasingTriplet(vector<int>& nums) {
 4         int n = nums.size();
 5         if (n < 3)return false;
 6         vector<int>dp(n, 1);
 7         for (int i = 1; i < n; ++i) {
 8             for (int j = 0; j < i; ++j) {
 9                 if (nums[j] < nums[i])
10                     dp[i] = max(dp[i], dp[j] + 1);
11             }
12             if (dp[i] == 3)return true;
13         }
14         return false;
15     }
16 };

 

2、符合题目要求的方法——最佳思路,但是比较难想

1)用两个数字m1代表当前最小的数,m2代表遍历到现在第二小的数,m2的位置不一定要在m1之后
2)那么当发现一个数大于m2的数的时候,就直接返回true
3)时间复杂度为n,空间复杂度为常数

 1 class Solution {
 2 public:
 3     bool increasingTriplet(vector<int>& nums) {
 4         int n = nums.size();
 5         int m1 = INT_MAX, m2 = INT_MAX;
 6         for (int i = 0; i < n; ++i) {
 7             if (nums[i] <= m1)m1 = nums[i];
 8             else if (nums[i] <= m2)m2 = nums[i];//要注意等号,也就是遇到相等的也要向后移动
 9             else return true;
10         }
11         return false;
12     }
13 };

 

3)另一种方法——思路很赞

1)Min[i]代表从0到i的最小值,Max[i]代表从i到n的最大值
2)如果nums[i]大于Min[i-1]并且小于Max[i+1],那么就返回真
3)时间复杂度为n,空间复杂度为n

 1 class Solution {
 2 public:
 3     bool increasingTriplet(vector<int>& nums) {
 4         int n = nums.size();
 5         if (n < 3)return false;
 6         vector<int> Min(n), Max(n);
 7         int i;
 8         Min[0] = nums[0], Max[n - 1] = nums[n - 1];
 9         for (i = 1; i < n; ++i) {
10             Min[i] = min(Min[i - 1], nums[i]);
11             Max[n - 1 - i] = max(Max[n - i], nums[n - 1 - i]);//注意下标
12         }
13         for (int i = 1; i < n - 1; ++i) {
14             if (nums[i] > Min[i - 1] && nums[i] < Max[i + 1])
15                 return true;
16         }
17         return false;
18     }
19 };
posted @ 2019-01-04 16:01  zhizhiyu  阅读(349)  评论(0编辑  收藏  举报