We need to find three elements in the array that are strictly increasing and appear in left-to-right order. We don't need to identify which three, only whether they exist.
The constraint on array size (up to 500,000) rules out O(n^2) or worse. The follow-up explicitly asks for O(n) time and O(1) space.
The central question is: as we scan through the array, what is the minimum information we need to track to know whether a valid triplet can be completed?
1 <= nums.length <= 5 * 10^5 → Half a million elements means O(n^2) would be 2.5 * 10^11 operations, far too slow. We need O(n log n) or better, ideally O(n).-2^31 <= nums[i] <= 2^31 - 1 → Full 32-bit integer range. We need to handle extreme values like Integer.MAX_VALUE and Integer.MIN_VALUE without overflow issues.Try every combination of three indices. Pick an i, then a j > i, then a k > j, and check whether the values are strictly increasing. This is a direct translation of the problem statement into code.
i from 0 to n-3:j from i+1 to n-2:nums[j] > nums[i], for each index k from j+1 to n-1:nums[k] > nums[j], return trueThe three nested loops re-scan overlapping ranges from scratch for every pair. The next approach precomputes the minimum value to the left and the maximum value to the right of each position, turning each check into O(1).
For any index j to be the middle element of a valid triplet, two conditions must hold:
Which specific elements satisfy these does not matter, only that they exist.
So we precompute, for every position, the smallest value to its left and the largest value to its right. Then for each j, we check whether leftMin[j] < nums[j] < rightMax[j].
leftMin array where leftMin[i] is the minimum value in nums[0..i]rightMax array where rightMax[i] is the maximum value in nums[i..n-1]j from 1 to n-2, check if leftMin[j-1] < nums[j] and nums[j] < rightMax[j+1]j exists, return true. Otherwise, return false.One detail in the indexing matters: when checking position j, we compare against leftMin[j-1] and rightMax[j+1], not leftMin[j] and rightMax[j]. The left and right candidates must come from positions strictly before and after j, since the triplet needs three distinct indices i < j < k.
This approach achieves O(n) time but uses two auxiliary arrays of size n. The next approach tracks the same information with two variables instead of two arrays, meeting the O(1) space requirement.
Instead of precomputing arrays, track two values as we scan left to right:
first: the smallest value seen so far (candidate for nums[i])second: the smallest value seen that is greater than some earlier value (candidate for nums[j])For any new number nums[k], if it is greater than second, we have found a triplet, because second was set based on an earlier value smaller than it.
The subtle case is when first is updated to a new, smaller value while second still holds a value that was set relative to the old first. This does not break the algorithm. Even though first now points to a different position, second still represents a valid second element: some element earlier in the array was smaller than second when second was assigned, and that element is still there. So any later value greater than second completes a valid triplet.
first and second to infinity (or Integer.MAX_VALUE)first, update first to this numbersecond, update second to this numberfirst and second, return trueThe invariant is: whenever second holds a finite value, some element strictly less than second appeared earlier in the array. The position of that element is never needed, only its existence.
When first drops below second (for example, num=0 after first=1, second=5), the invariant still holds. second=5 was assigned when first was 1, and that element with value 1 sits to the left of the position where second was set. A later value greater than 5 therefore forms a valid triplet: the value-1 element, the value-5 element, and the new element, in left-to-right order.
This greedy generalizes to the Longest Increasing Subsequence problem, where maintaining the smallest tail value for subsequences of each length gives the O(n log n) LIS algorithm. Here the target length is 3, so two variables suffice.