334. 递增的三元子序列
题目
给你一个整数数组 nums ,判断这个数组中是否存在长度为 3 的递增子序列。
如果存在这样的三元组下标 (i, j, k) 且满足 i < j < k ,使得 nums[i] < nums[j] < nums[k] ,返回 true ;否则,返回 false 。
示例1
输入: nums = [1,2,3,4,5]
输出: true
解释: 任何 i < j < k 的三元组都满足题意
示例2
输入:nums = [2,1,5,0,4,6]
输出:true
解释:三元组 (3, 4, 5) 满足题意,因为 nums[3] == 0 < nums[4] == 4 < nums[5] == 6
题解
双循环
对于数组nums = [2,1,5,0,4,6];
- 通过从左到右遍历,构建当前值之前最小值数组left=[2,1,1,0,0,0];
- 通过从右到左遍历,构建当前值之前最大值数组right=[6,6,6,6,6,6];
- 再次从[1,nums.length-1]枚举nums值,如果在枚举过程中当前下标x;存在nums[i] > left[i] && nums[i] < right[i]; 返回true;
时间复杂度,因为枚举3次nums,所以时间复杂度为O(n);
空间复杂度;因为构建两个数组left,right,所以空间复杂度为O(n)
根据上述思路编辑代码如下
代码
var increasingTriplet = function (nums) {
const len = nums.length
const right = []
right[len - 1] = nums[len - 1]
for (let i = len - 2; i >= 0; i--) {
const c = Math.max(right[i + 1], nums[i])
right[i] = c
}
const left = [nums[0]]
for (let i = 1; i < len; i++) {
const c = Math.min(nums[i], left[i - 1])
left[i] = c
}
for (let i = 1; i < len - 1; i++) {
if (nums[i] > left[i] && nums[i] < right[i]) return true
}
return false
}
贪心
对于nums数组;找到3个连续递增的数;假设这3个数为x,y,z;
枚举过程中,在x < y的条件下,尽可能的降低y的值,保证找到z的可能性最大;
所以有任意nums[i],如果nums[i] <= x;更新x;如果num[i] >x && nums[i] <= y;更新y;如果nums[i] > y 返回true;否则返回false;
贪心,只用一次枚举即可解决问题
代码
var increasingTriplet = function (nums) {
let n1 = nums[0]
let n2 = Infinity
for (let i = 1; i < nums.length; i++) {
if (n1 >= nums[i]) {
n1 = nums[i]
} else if (n2 >= nums[i]) {
n2 = nums[i]
} else {
return true
}
}
return false
}