这是我参与2022首次更文挑战的第10天,活动详情查看:2022首次更文挑战
题目
给你一个整数数组 nums ,判断这个数组中是否存在长度为 3 的递增子序列。
如果存在这样的三元组下标 (i, j, k) 且满足 i < j < k ,使得 nums[i] < nums[j] < nums[k] ,返回 true ;否则,返回 false 。
示例
输入: nums = [1,2,3,4,5]
输出: true
解释: 任何 i < j < k 的三元组都满足题意
输入: nums = [5,4,3,2,1]
输出: false
解释: 不存在满足题意的三元组
输入:nums = [2,1,5,0,4,6]
输出:true
解释:三元组 (3, 4, 5) 满足题意,因为 nums[3] == 0 < nums[4] == 4 < nums[5] == 6
提示
1 <= nums.length <= 5 * 10-2<= nums[i] <= 2- 1
解题思路
三层循环
遇到需要多个元素进行比较的题,可能最容易想到的就是多层循环,简单粗暴,上来几个for循环下去就搞定了。
class Solution {
public boolean increasingTriplet(int[] nums) {
int n = nums.length;
for(int i = 0; i < n - 2; ++i){
for(int j = i + 1; j < n - 1; ++j){
for(int k = j + 1; k < n; ++k){
if(nums[i] < nums[j] && nums[j] < nums[k]){
return true;
}
}
}
}
return false;
}
}
一遍遍历
多层遍历虽然是最容易实现的,但是其时间复杂度也是最高的,从上面的结果我们可以看到,直接就超出时间限制了,必须对其进行优化才行。
在这里可以先将前面两个元素定义出来,用类似取最大值的方式,来判断是否符合条件。
- 第一个元素
f,取值首位元素 - 第二个元素
s,先设置成最大值,然后遍历后续元素,将其更新为最接近f的次小值
class Solution {
public boolean increasingTriplet(int[] nums) {
int n = nums.length;
if(n < 3){
return false;
}
int f = nums[0], s = Integer.MAX_VALUE;
for(int i = 1; i < n; ++i){
if(nums[i] > s){
// 由于s必定大于f,如果当前元素大于s表示条件成立,直接返回结果
return true;
}else if(nums[i] > f){
// 当前元素小于s且大于f,更新s的值,使其变得更小更接近f
s = nums[i];
}else{
// 以上条件都不满足,更新f为最小值
f = nums[i];
}
}
return false;
}
}