题目描述
给定一个未排序的数组,判断这个数组中是否存在长度为 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
首先题目要求时间复杂度O(n),空间复杂度O(1)。这就要求我们只扫描一遍,并且只可以使用有限个变量,那么使用暴力法是不可能的。双指针法?好像用不上哎。排序再处理?不行,要求O(n)。使用TreeMap?不行,要求O(n)。经过了5分钟的思考,嗯,我们可以试试找长度为2的递增子序列。那么可以用变量min记录之前遇到的最小的数字,如果当前数字比min大,那么我们就找到了长度为2的子序列;如果当前数字比min小,那么就更新min。
扩展下,题目要求长度为3的子序列。那么我们可以维护两个变量min1, min2,使得min1始终小于min2,当我们遇到一个数num,且num > min2时,就满足了min1<min2<num。此时,我们就找到了第一组递增三元子序列,返回true即可。
P.S. 好高兴啊,这道题是我刷了好久的题,第一次就想到了最优解法。
class Solution {
public boolean increasingTriplet(int[] nums) {
int min1 = Integer.MAX_VALUE, min2 = Integer.MAX_VALUE;
for(int num:nums) {
if(num < min1)
min1 = num;
else if(num > min1 && num < min2)
min2 = num;
else if(num > min2)
return true;
}
return false;
}
}