查看: 3133| 回复: 3
跳转到指定楼层
上一主题 下一主题
收起左侧

最长等差数列问题

全局:

注册一亩三分地论坛,查看更多干货!

您需要 登录 才可以下载或查看附件。没有帐号?注册账号

x
本帖最后由 wwwyhx 于 2011-5-28 14:15 编辑

以排好序的数组,找出数组最长等差数列的长度,比如
1 3 5 6 8 9 10 12 13 14
最长等差数列为6 8 10 12 14

上一篇:Google : 求1到n个数中,1出现的个数
下一篇:Microsoft : Create two evenly balanced teams for a game of soccer.
🔗
Navi 2011-5-27 02:37:03 | 只看该作者
全局:
1 把数组每个元素分别+1,+2,。。。,+(a[len-1]-a[i]),
2 每次update能组成的最长等差数列的元素个数,和公差
3 从而得到最长的等差数列的公差输出

没想到很好的办法。。
回复

使用道具 举报

🔗
 楼主| wwwyhx 2011-5-28 14:26:30 | 只看该作者
全局:
本帖最后由 wwwyhx 于 2011-5-28 14:29 编辑

常规解法的时间复杂度是n^3, 也就是先确定等差数列头两个元素, a, a[j],再往后搜索以这两个元素开头的所有满足条件的数列,这样就存在了重复计算,因该可以用DP优化。比如我选择了a[0]和a[1], 那么我可能要搜索从a[2]一直到a[n-1]的所有元素,当我选择a[0],a[2]时,可能要搜索所有a[3]一直到a[n-1]的所有元素,存在重复计算。

DP状态转移公式:
设F(i,j)为以数列a[i],a[j]结尾的等差数列,i<j,则
F(i,j) = {1 +  F(x,i) if (x存在), 2 if (x不存在) }
其中x可以用二分来查找,n^2*logn
[/i]
回复

使用道具 举报

🔗
 楼主| wwwyhx 2011-5-28 14:36:27 | 只看该作者
全局:

  1. int BinarySearch(int a[], int n, int nVal)
  2. {
  3.         assert(a);
  4.         if (0 == n) return -1;

  5.         int nBeg = 0;
  6.         int nEnd = n-1;

  7.         while (nBeg <= nEnd)
  8.         {
  9.                 int nMid = (nBeg+nEnd)/2;
  10.                 if (a[nMid] == nVal)
  11.                         return nMid;

  12.                 if (a[nMid] > nVal)
  13.                         nEnd = nMid-1;
  14.                 else
  15.                         nBeg = nMid+1;
  16.         }

  17.         return -1;
  18. }

  19. int GetLength(int a[], int n)
  20. {
  21.         assert(a && n>0);

  22.         int** pDP = new int*[n];
  23.         for (int i = 0; i < n; i++)
  24.         {
  25.                 pDP[i] = new int[n];
  26.                 memset(pDP[i], 0, sizeof(int)*n);
  27.         }

  28.         int nMax = 0;
  29.         for (int i = 0; i < n; i++)
  30.         {
  31.                 for (int j = i+1; j < n; j++)
  32.                 {
  33.                         int nDiff = a[j]-a[i];
  34.                         int nIndex = BinarySearch(a, i, a[i]-nDiff);

  35.                         if (nIndex >= 0)
  36.                                 pDP[i][j] = pDP[nIndex][i]+1;
  37.                         else
  38.                                 pDP[i][j] = 2;

  39.                         nMax = pDP[i][j] > nMax ? pDP[i][j] : nMax;
  40.                 }
  41.         }

  42.         for (int i = 0; i < n; i++)
  43.                 delete pDP[i];
  44.         delete []pDP;

  45.         return nMax;
  46. }
复制代码
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册账号
隐私提醒:
  • ☑ 禁止发布广告,拉群,贴个人联系方式:找人请去🔗同学同事飞友,拉群请去🔗拉群结伴,广告请去🔗跳蚤市场,和 🔗租房广告|找室友
  • ☑ 论坛内容在发帖 30 分钟内可以编辑,过后则不能删帖。为防止被骚扰甚至人肉,不要公开留微信等联系方式,如有需求请以论坛私信方式发送。
  • ☑ 干货版块可免费使用 🔗超级匿名:面经(美国面经、中国面经、数科面经、PM面经),抖包袱(美国、中国)和录取汇报、定位选校版
  • ☑ 查阅全站 🔗各种匿名方法

本版积分规则

>
快速回复 返回顶部 返回列表