问题描述:
给定一个未排序的数组,判断这个数组中是否存在长度为 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
示例 2:
输入: [5,4,3,2,1] 输出: false
解题思路:
遍历一遍数组完成目标。
1、用2个变量curSubMin和curSubMax分别存放当前遍历的最小值和最大值的有序序列,比如数组[2,1,5,0,3]那么curSubMin=1,curSubMax=5
2、用一个变量min存放当前已经遍历的最小值,以便出现nums[i]小于curSubMax,并且大于min时,那么当前最优的curSubMin和curSubMax就应该是min和nums[i]
提交代码如下:
bool increasingTriplet(int* nums, int numsSize) {
if(nums==NULL || numsSize<3)
{
return false;
}
int curSubMax=0x80000000,curSubMin=nums[0];
int min=0x7fffffff;//最大整数,用于保存最小的数
int count=1,i=1;
int j=0;
for(j=1;j<numsSize;j++)//找出数组中前2个有序的数字curSubMin/curSubMax
{
// printf("nums[%d]=%d,curSubMin=%d,CurSubMax=%d\n",j,nums[j],curSubMin,curSubMax);
if(nums[j]<curSubMin)
{
curSubMin=nums[j];
}
else if(nums[j]>curSubMin)
{
curSubMax=nums[j];
count++;
}
if(curSubMax!=0x8fffffff)
{
break;
}
}
for(i=j+1;i<numsSize;i++)
{
// printf("1、curSubMin=%d, curSubMax=%d, min=%d, nums[%d]=%d,count=%d\n",curSubMin,curSubMax,min,i,nums[i],count);
if(nums[i]>curSubMax)//nums[i]大于当前最大值
{
curSubMax=nums[i];
count++;
}
else if(nums[i]<curSubMax)//nums[i]小于当前最大值
{
if(nums[i]>curSubMin)//curSubMin<nums[i]<curSubMax
{
curSubMax=nums[i];
}
else if(nums[i]<curSubMin)//nums[i]<curSubMin
{
if(nums[i]<=min)//如果nums[i]小于当前遍历的所有最小值,那么min等于nums[i]
{
min=nums[i];
}
else//min<nums[i]<curSubMin,那么把当前的最大最小值替换
{
curSubMin=min;
curSubMax=nums[i];
count=2;
}
}
}
if(count==3)
{
break;
}
}
if(count==3)
{
return true;
}
return false;
}