问题描述
来源:LeetCode第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 = [5,4,3,2,1]
输出:false
解释:不存在满足题意的三元组
示例 3:
输入:nums = [2,1,5,0,4,6]
输出:true
解释:三元组 (3, 4, 5) 满足题意,因为 nums[3] == 0 < nums[4] == 4 < nums[5] == 6
提示:
1<=nums.length<=10^5
-2^31<=nums[i]<=2^31-1
问题分析
长度为3的递增子序列,序列可以不是连续的。只需要使用两个变量即可,一个记录扫描过的最小值,一个记录扫描过的第二小的值。他们的初始值都是Integer.MAX_VALUE
要保证最小值和第二小的值尽可能的小。
如果当前数字比最小值还小,我们就更新最小值
如果当前数字大于最小值并且小于第二小的值,我们就更新第二小的值
如果当前数字大于第二小的值,说明找到了递增的三元子序列,直接返回true。
这里前两条很好理解,我们主要看一下第三条,因为第二小的值默认是Integer.MAX_VALUE,如果当前数字比他大,说明第二小的值已经被赋值了,第二小的值被赋值的条件是最小值也已经被赋值了,因为如果最小值没有被赋值的话,那么最小值优先被赋值。所以这里有个隐含的条件就是,如果第二小的值被赋值了,那么最小的值肯定存在。来看下代码
public boolean increasingTriplet(int[] nums) {
//3个数字,small记录最小的数字
int small = Integer.MAX_VALUE;
//mid记录中间的数字
int mid = Integer.MAX_VALUE;
for (int num : nums) {
if (num <= small) {
//记录遍历过的最小值
small = num;
} else if (num <= mid) {
//记录比small大的最小值,也就是mid的值
mid = num;
} else {
//mid如果赋值了,那么之前肯定有个比
//mid小的值,这里又有个比mid大的值,
//所以他们三个可以构成递增的三元子序列
return true;
}
}
return false;
}
联系客服