1、双向遍历数组记录
我们可以使用两个数组分别记录对于原数组中的第 i 位,其左边和右边的最小值和最大值,若存在有一位满足其左侧的最小值小于其自身且其自身小于其右侧的最大值,则直接返回 true 。
class Solution {
public:
bool increasingTriplet(vector<int> &nums) {
int n = nums.size();
vector<int> LeftMin(n, INT_MAX), RightMax(n, INT_MIN);
LeftMin[0] = nums[0];
RightMax[n - 1] = nums[n - 1];
for (int i = 1; i < n; ++i) {
LeftMin[i] = min(LeftMin[i - 1], nums[i]);
RightMax[n - i - 1] = max(RightMax[n - i], nums[n - i - 1]);
}
for (int i = 0; i < n; ++i) {
if (nums[i] > LeftMin[i] && nums[i] < RightMax[i]) {
return true;
}
}
return false;
}
};
2、贪心
我们可以使用first
记录当前遍历的最小值,second
记录当前遍历的第二小值。当我们每次遍历到一个新的数字时,我们进行判断:
- 若新的值大于此时的
second
,说明我们已经找到满足条件的三元子序列; - 若新的值大于此时的
first
,说明此时还有更小的第二小值,之前的第二小值肯定没有新的第二小值能够满足条件,我们对其进行更新; - 若新的值小于等于此时的
first
,说明此时的最小值还可以进行更新。
最终我们遍历完整个数组,判断有无这样的三元组即可。
class Solution {
public:
bool increasingTriplet(vector<int>& nums) {
int n = nums.size();
if (n < 3) {
return false;
}
int first = nums[0], second = INT_MAX;
for (int i = 1; i < n; i++) {
int num = nums[i];
if (num > second) {
return true;
} else if (num > first) {
second = num;
} else {
first = num;
}
}
return false;
}
};