求数组中最长递增子序列

  • 动态规划求解

int calculate(int a[], int n)
{
	int i;
	int maxV;
	//maxLen[i]代表截止到下标为i(包括i)的最长子序列的长度
	int * maxLen = (int *)malloc(n*sizeof(int));

	for(i=0;i<n;i++)
	{
		maxLen[i]=1;
		for(int j = 0;j<i;j++)
		{
			if(a[i]>a[j] && maxLen[j]+1>maxLen[i])
			{
				maxLen[i] = maxLen[j]+1;
			}
		}
	}
	maxV = max(maxLen,n);
	free(maxLen);

	return maxV;
}

时间复杂的为O(n*n)


  • 进一步分析

    如果前i-1个元素的任何一个递增子序列的最大值小于第i个元素,那么就可以构成一个新的递增子序列。重要的是我们要保证新的递增子序列尽可能的长。


  • int calculate(int a[],int n)
    {
    
    	int i,j;
    
    	//如果存在含有元素相同个数的多个子序列,长度为i,将多个子序列的最大值中的最小值存入minV[i]
    	int * maxV = (int *)malloc(sizeof(int) * (n+1));
    	//maxLen[i]代表截止到下标为i(包括i)的最长子序列的长度
    	int * maxLen = (int *)malloc(sizeof(int) * n);
    	//记录最长子序列的长度,初始为1
    	int max = 1;
    
    	maxV[1] = a[0];
    	maxV[0] = min(a,n)-1;
    
    	for(i=0;i<n;i++)
    	{
    		//初始化为1
    		maxLen[i]=1;
    	}
    
    	for(i=1;i<n;i++)
    	{
    		for(j=max;j>=0;j--)
    		{
    			//如果当前值a[i]大于长度为j的递增子序列,则可以构成长度为j+1的递增子序列。
    			if(a[i]>maxV[j])
    			{
    				maxLen[i]=j+1;
    				break;
    			}
    		}
    	}
    
    	//如果截止到下标为i(包括i)的最长子序列的长度大于记录max,则将max赋值为maxLen[i]
    	if(maxLen[i]>max)
    	{
    		max=maxLen[i];
    		//该长度为maxLen[i]的子序列的最大值一定为a[i]
    		maxV[maxLen[i]]=a[i];
    	}
    	else if(maxV[j] < a[i] && a[i] < maxV[j+1])
    	{
    		maxV[j+1] = a[i];
    	}
    
    	free(maxV);
    	free(maxLen);
    
    	return max;
    
    }

    时间复杂度O(n*n)


参考书籍:《编程之美》

你可能感兴趣的:(求数组中最长递增子序列)