Chinaunix首页 | 论坛 | 博客
  • 博客访问: 986875
  • 博文数量: 150
  • 博客积分: 3017
  • 博客等级: 少校
  • 技术积分: 3829
  • 用 户 组: 普通用户
  • 注册时间: 2011-11-19 14:40
个人简介

Now in Baidu WISE team

文章分类

全部博文(150)

文章存档

2014年(8)

2013年(31)

2012年(111)

分类: C/C++

2012-12-23 00:29:20

原题目是求一个无序数组中最长的等差数列。
求随机数构成的数组中找到长度大于=3 的最长的等差数列, 输出等差数列由小到大:
如果没有符合条件的就输出
格式:
输入[1,3,0,5,-1,6]
输出[-1,1,3,5]
 
 
解法如下:
1.排序
2.设极值分别为min, max,那么公差范围为(1..max-min);
3.公差d从(1..max-min)循环,求出每次的最长的数列长度f(d)
<根据已得到的数列的长度,还可以进一步减少循环次数>
 
所以该题目基础是求出一个有序数组中公差为d的最长等差数列。
 
较简单动态规划:
设等差数列的起始下标为s,当前下标为i,从s到i,构成的最长的等差数列长度为f(s,i),有
  f(s,i+1) = f(s,i) +1 ( input[i+1] == input[s] + f(s,i)*d)
             f(s,i)    ( input[i+1] != input[s] + f(s,i)*d)
 
最长的数列长度为:
    maxLen = max{f(s,i) s∈[1 ..  max-min] i∈[0,sizeof(input)) }
 
算法时间复杂度应为n的平方,空间复杂度可优化至O(1) (代码中为O(n))
 
代码如下:


点击(此处)折叠或打开

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #define MAX 1000

  4. void GetSeq(int *input, int size, int d){
  5.     if(input == NULL) return;
  6.     int result[MAX] = {0};
  7.     
  8.     int startIndex = 0;
  9.     int maxLen = 0;
  10.     int maxLenStartIndex = -1;
  11.     for(;startIndex < size-maxLen; startIndex++){
  12.         int i = startIndex;
  13.         result[i] = 1;
  14.         i++;
  15.         for(;i<size;i++){
  16.             result[i] = result[i-1];
  17.             if(input[i] == input[startIndex] +result[i-1]*d){
  18.                 result[i]++;
  19.                 if(result[i]> maxLen){
  20.                     maxLen = result[i];
  21.                     maxLenStartIndex = startIndex;
  22.                 }
  23.             }
  24.             else if(input[i] > input[startIndex] + result[i-1]*d)
  25.                 break;
  26.         }
  27.         }
  28.     printf("Max sequence start index: %d, length: %d \n", maxLenStartIndex, maxLen);
  29. }

  30. int main(){
  31.     int input[] = {1,3,4,6,7,9,10,12,13,15,16,18,21,24};
  32.     GetSeq(input, sizeof(input)/sizeof(int), 3);
  33. }


阅读(3690) | 评论(0) | 转发(1) |
给主人留下些什么吧!~~