Given an unsorted array return whether an increasing subsequence of length 3 exists or not in the array.
Formally the function should:
Return true if there exists i, j, k
such that arr[i] < arr[j] < arr[k] given 0 ≤ i < j < k ≤ n-1 else return false.
Your algorithm should run in O(n) time complexity and O(1) space complexity.
Examples:
Given [1, 2, 3, 4, 5]
,
return true
.
Given [5, 4, 3, 2, 1]
,
return false
.
注意这个测试用例:[1, 2, 0, 3] 返回true,因为其中包含 [1,2,3] 是递增的。[1, 1, 1, 2,2,2] 返回 false 。
思路是用两个变量,min存储 迄今为止的最小值,secondMin存储 "通常”在最小值索引之后的 第二小值( min ≠ secondMin )。为什么说是“通常”呢?如:
initial : [1, 2, 0, 3]
, min
= MAX
, secondMin = MAX
loop1 : [1, 2, 0, 3]
, min
= 1
, secondMin
= MAX
loop2 : [1, 2, 0, 3]
, min
= 1
, secondMin
= 2
loop3 : [1, 2, 0, 3]
, min
= 0
, secondMin
= 2
// <- Uh oh, 0
technically appeared after 2
loop4 : return true
since 3
>
min && 3 >
secondMin
// Isn't this a violation??
存在违反了吗?并不。如果你仔细观察了,会发现,当我们把 secondMin
从 MAX
更新为其他值时,显然之前肯定有一个值比它小
(该值之前已经被赋值给了min
).
所以,当你一旦找到某个值大于 secondMin
时,你肯定会找到一个递增三连。
总结就是:
a). i <= min < secondMin, 只更新
min, 这不会改变当前的局面:min <secondMin.
b). min < i <= secondMin, 只更新 secondMin,那么 min
<
secondMin 仍然保持.
c.) min < secondMin < i, 那么我们找到了一个递增三连。
public class Solution {
public boolean increasingTriplet(int[] nums) {
int min = Integer.MAX_VALUE, secondMin = Integer.MAX_VALUE;
for(int num : nums){
if(num <= min) min = num;
else if(num < secondMin) secondMin = num;
else if(num > secondMin) return true;
}
return false;
}
}