1. 题目描述

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

数学表达式如下:

如果存在这样的 i, j, k, 且满足 0 ≤ i < j < k ≤ n-1, 使得 arr[i] < arr[j] < arr[k] ,返回 true ; 否则返回 false 。 说明: 要求算法的时间复杂度为 O(n),空间复杂度为 O(1) 。

示例 1:

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

示例 2:

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

2. 解题思路

方法一:

我们可以设置两个变量one和two,保证one小于two,若遍历到一个数大于two,则满足三个数递增的要求,返回true

该方法的时间复杂度为O(n)空间复杂度为O(1)

方法二:

我们还可以使用贪心算法来解决这个问题。

循环遍历数组,不断更新数组中出现的最大值和最小值,如果出现一个大于最大值的数,则表示存在长度为3的递增子序列,返回true。

具体步骤如下:

  • 首先定义两个变量small和big,分别存放三个数字中的比较小的两个,
  • 循环数组,实时捕获最小的两个数,同时判断这个两个数后面是否存在一个数比这两个数都大,如果存在,就返回true,否则就返回false。

该方法的时间复杂度为O(n)空间复杂度为O(1)

3. 代码实现

方法一:

  1. /**
  2. * @param {number[]} nums
  3. * @return {boolean}
  4. */
  5. var increasingTriplet = function(nums) {
  6. if(nums.length < 3) return false
  7. let one, two
  8. for(const num of nums){
  9. if(num > two){
  10. return true
  11. }else if(num > one){
  12. two = num
  13. }else{
  14. one = num
  15. }
  16. }
  17. return false
  18. };

方法二:

  1. /**
  2. * @param {number[]} nums
  3. * @return {boolean}
  4. */
  5. var increasingTriplet = function(nums) {
  6. if(nums.length < 3) return false
  7. let small = Number.MAX_SAFE_INTEGER
  8. let big = Number.MAX_SAFE_INTEGER
  9. for(let i = 0; i< nums.length; i++){
  10. if(nums[i] <= small){
  11. small = nums[i]
  12. }else if(nums[i] <= big){
  13. big = nums[i]
  14. }else{
  15. return true
  16. }
  17. }
  18. return false
  19. };

4. 提交结果

方法一:
334. 递增的三元子序列 - 图1
方法二:
334. 递增的三元子序列 - 图2