给定一个整数数组,返回它其中最长的连续整数数列长度。
测试数据:
例如 a[] = {100,4,200,1,3,2} 因为其中包含1,2,3,4所以返回4.
原题链接:http://www.51weixue.com/thread-518-1-1.html
我的做法:
1、第一次遍历输出数组,获取必要信息,构造正整数A数组,负整数B数组。
2、第二次遍历正整数B数组,求出正整数中最长的长度的子数组,并记录包含0的子数组的长度,以便计算跨越正负区间的子数组长度。
3、第三次遍历负整数C数组,求出负整数中最长的长度的子数组,并记录包含-1的子数组的长度,以便计算跨越正负区间的子数组长度。
4、比较并得出最长连续子数组的长度。
时间复杂度:O(3n),空间复杂度:O(3n)。
代码如下:
#include<stdio.h>
#include<memory.h>
const int N = 1000 ;
int LongestSubArrary(int *ptrA,int n) ;
inline int max(int x, int y) ;
int main(void)
{
int A[N] ;
int i,n,t ;
freopen("in.txt","r",stdin) ;
scanf("%d",&t) ;
while(t-- > 0)
{
scanf("%d",&n) ;
for(i = 0 ; i < n ; ++i)
{
scanf("%d",&A[i]) ;
}
printf("%d\n",LongestSubArrary(A,n)) ;
}
return 0 ;
}
int LongestSubArrary(int *ptrA,int n)
{
int B[N],C[N] ;
int i,nLongestLen,nBeg,nEnd,nZeroLen ;
int fFirst ,fStart,fCalc ;
int nNegaLongestLen,nNegaBeg,nNegaEnd,nNegaZeroLen ;
int fNegaFirst ;
int nLen ;
int nMegaLen = 0 ;
memset(B,0,sizeof(B)) ;
memset(C,0,sizeof(C)) ;
nBeg = 1 ;
nEnd = 0 ;
nNegaBeg = -1 ;
nNegaEnd = -2 ;
fFirst = 0 ;
fNegaFirst = 0 ;
for(i = 0 ; i < n ; ++i)
{
if(ptrA[i] >= 0) //正数和0
{
if(0 == fFirst)
{
nBeg = ptrA[i] ;
nEnd = ptrA[i] ;
fFirst = 1 ;
}
else if(nBeg > ptrA[i])
{
nBeg = ptrA[i] ;
}
else if(ptrA[i] > nEnd)
{
nEnd = ptrA[i] ;
}
B[ptrA[i]] = 1 ;
}
else //负数
{
if(0 == fNegaFirst)
{
nNegaBeg = ptrA[i] ;
nNegaEnd = ptrA[i] ;
fNegaFirst = 1 ;
}
else if(nNegaBeg > ptrA[i])
{
nNegaBeg = ptrA[i] ;
}
else if(ptrA[i] > nNegaEnd)
{
nNegaEnd = ptrA[i] ;
}
C[-ptrA[i]] = 1 ;
}
}
/******************正数******************/
fStart = 0 ;
nLongestLen = 0 ;
nLen = 0 ;
nZeroLen = 0 ;
fCalc = 0 ;
for(i = nBeg ; i <= nEnd+1 ; ++i)
{
if(1 == B[i])
{
nLen++ ;
fStart = 1 ;
}
else if(0 == B[i] && 1 == fStart)
{
if(nLen > nLongestLen)
{
nLongestLen = nLen ;
if(0 == nBeg && 0 == fCalc)
{
nZeroLen = nLen ;
fCalc = 1 ;
}
}
nLen = 0 ;
fStart = 0 ;
}
}
/**************************/
/*******************负数*****************/
fStart = 0 ;
nNegaLongestLen = 0 ;
nLen = 0 ;
nNegaZeroLen = 0 ;
fCalc = 0 ;
for(i = nNegaBeg ; i <= nNegaEnd+1 ; ++i)
{
if(1 == C[-i])
{
nLen++ ;
fStart = 1 ;
}
else if(0 == C[-i] && 1 == fStart)
{
if(nLen > nNegaLongestLen)
{
nNegaLongestLen = nLen ;
if(-1 == nNegaEnd && 0 == fCalc)
{
nNegaZeroLen = nLen ;
fCalc = 1 ;
}
}
nLen = 0 ;
fStart = 0 ;
}
}
/****************************************/
if(-1 == nNegaEnd && 0 == nBeg)
{
nMegaLen = nZeroLen + nNegaZeroLen ;
}
return max(max(nLongestLen,nNegaLongestLen),nMegaLen) ;
}
int max(int x, int y)
{
return x > y ? x : y ;
}
测试数据:
7
5
5 0 3 -1 1
7
-1 -5 1 -2 0 2 3
11
-1 0 1 2 3 5 6 7 8 9 10
10
-4 -3 -2 5 6 7 2 1 -1 4
4
-1 0 -2 2
3
0 1 2
3
-1 -3 -5