给定一个未排序的数组,判断这个数组中是否存在长度为 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
思路:两种思路
思路一:使用d[i]数组保存以i结尾的非连续的递增序列的长度,max保存元素最大值,imax是最大值得索引位置,min保存元素最小值,imin是最小值得索引位置。
有以下几种情况,
若nums[i]大于nums[i-1]且大于max,那么d[i]=max(d[i-1],d[imax])+1;
若nums[i]大于nums[i-1]且大于min小于max,那么d[i]=max(d[i-1],d[imin])+1;
若nums[i]小于nums[i-1]且大于min小于max,那么d[i]=d[imin]+1;
若最后nums[i]小于min,那么d[i]=1,即它自身的长度;
class Solution {
//不连续的递增
public boolean increasingTriplet(int[] nums) {
if(nums.length<3){return false;}
int max=nums[0];int imax=0;
int min=nums[0];int imin=0;
int[] d = new int[nums.length];//存以i结尾的最长不连续递增序列长度
d[0]=1;
int count=0;
for(int i=1;i<nums.length;i++){
if(nums[i]>nums[i-1]&&nums[i]>max){
d[i]=Math.max(d[i-1],d[imax])+1;
}else if(nums[i]>nums[i-1]&&nums[i]>min){
d[i]=Math.max(d[i-1],d[imin])+1;
}else if(nums[i]>min){
d[i]=d[imin]+1;
}else{
d[i]=1;
}
//若长度达到3即满足了
if(d[i]==3){
return true;
}
if(max<nums[i]){
max=nums[i];
imax=i;
}
if(min>nums[i]){
min=nums[i];
imin=i;
}
}
return false;
}
}
思路2:使用num1和num2两个数。保证num1小于nums2,若遍历到一个数大于nums2,则满足3个数递增。返回true
class Solution {
public boolean increasingTriplet(int[] nums) {
int num1 = Integer.MAX_VALUE;
int num2 = Integer.MAX_VALUE;
for(int num : nums){
if(num <= num1){
num1 = num;
}else if(num > num1 && num <=num2){
num2 = num;
}else{
return true;
}
}
return false;
}
}