楼主: wwwyhx
跳转到指定楼层
上一主题 下一主题
收起左侧

Google : 求最长等差数列

🔗
swordsnow 2011-9-5 20:28:25 | 只看该作者
全局:
把差hash到1,2,3,4...不就行了(最多只有O(N^2)种差)回复 10# wwwyhx
回复

使用道具 举报

🔗
 楼主| wwwyhx 2011-9-5 23:04:47 | 只看该作者
全局:
把差hash到1,2,3,4...不就行了(最多只有O(N^2)种差)回复  wwwyhx
swordsnow 发表于 2011-9-5 20:28



    可以是可以,一个是这个方法太ugly了, 还有一个是要用hash还不如用二楼的方法更直接
回复

使用道具 举报

🔗
sing1ee 2013-9-5 11:31:21 | 只看该作者
全局:
epic 发表于 2011-7-28 15:34
平方的算法应该还是不难的吧?
首先做一个hash表,维护key={a,b} value=c,含义是以a开始的差为b的等差数列 ...

我觉得这个方法有问题。
hash表查找num[i], num[i]-num[j]之后,如何更新呢?
这个hash表示的是最长的长度,而不是有多少个差是b的值?
请指教。
回复

使用道具 举报

🔗
epic 2013-11-18 04:20:19 | 只看该作者
全局:
本帖最后由 epic 于 2013-11-18 04:26 编辑
sing1ee 发表于 2013-9-5 11:31
我觉得这个方法有问题。
hash表查找num, num-num[j]之后,如何更新呢?
这个hash表示的是最长的长度,而 ...
  1. 我发现我确实是打错了,是查num[j],num[j]-num[i]的值来更新num[i],num[j]-num[i]……

  2. for (int i = n-1; i>=0; --i) //注意顺序
  3. for (int j = i+1;j<n;++j)
  4. {
  5.      差 d = num[j] - num[i]
  6.      MAP[num[i],d] = MAP [num[j],d] + 1
  7. }
复制代码
回复

使用道具 举报

🔗
梦流星 2015-6-30 10:59:32 | 只看该作者
全局:
本帖最后由 梦流星 于 2015-6-30 11:02 编辑

  1. #include <iostream>
  2. #include <algorithm>
  3. #include <cstring>

  4. using namespace std;

  5. int n;
  6. int a[10001];

  7. //let's assume that sequence s(n) = a[i] s(n+1) = a[j]
  8. //dp_matrix[i][j] represent the count of sequence in s
  9. short int dp_matrix[10001][10001];

  10. int main()
  11. {
  12.     cin >> n;
  13.     for (int i = 0; i < n; ++i)
  14.         cin >> a[i];
  15.     memset(dp_matrix, 0, sizeof(dp_matrix[0][0]) * 10001 * 10001);
  16.     short int max_len = 0;

  17.     for (int i = 0; i < n; ++i)
  18.     {   
  19.         for (int j = i + 1; j < n; ++j)
  20.         {   
  21.             bool delta_is_match = false;
  22.             int cur_delta = a[j] - a[i];
  23.             for (int k = i-1; k >= 0; --k)
  24.             {   
  25.                 int delta_i_to_k = a[i] - a[k];
  26.                 if (delta_i_to_k == cur_delta)
  27.                 {   
  28.                     if (dp_matrix[i][j] < dp_matrix[k][i] + 1)
  29.                         dp_matrix[i][j] = dp_matrix[k][i] + 1;
  30.                     else
  31.                         cout << "k:" << k << " i:" << i << " j:" << j << endl;
  32.                     delta_is_match = true;
  33.                     break;
  34.                 }   
  35.             }   
  36.             if (delta_is_match == false)
  37.             {   
  38.                 dp_matrix[i][j] = 2;
  39.             }   
  40.             if (dp_matrix[i][j] > max_len)
  41.             {   
  42.                 max_len = dp_matrix[i][j];
  43.             }   
  44.         }   
  45.     }   
  46.     //for_each(&dp_matrix[0], &dp_matrix[n], [=](short int p[]){for_each(&p[0], &p[n],[](short int n){cout<<n<<' ';});cout<<endl;});
  47.     cout << max_len << endl;
  48.     return 0;
  49. }
复制代码
我的代码我觉得应该是对的  但是wa, 我还在想为什么..我算出来的结果比正确结果低  有一个正确结果是25  我算出来是7....
回复

使用道具 举报

🔗
梦流星 2015-6-30 11:06:24 | 只看该作者
全局:
本帖最后由 梦流星 于 2015-6-30 11:21 编辑

知道了....
他的意思是给出的数据不是一个数列 array 而是一个集合 set
让你在set里面找能够拼出来最长的, 这样的情况只要对set进行排序就可以按照上面的code解了....
但是目前还会tle  算法性能要优化一下, 我得看看

给个case, 输入:
100
1627
757
3019
4933
4237
2787
2265
6035
699
4121
235
2091
6325
4411
1859
3947
4527
6093
641
1047
2497
5107
1105
1975
5281
5687
3599
4585
4469
119
6383
5165
5513
409
3309
3367
1801
4353
3077
1569
2555
583
6267
3135
351
815
1395
2033
3541
5629
1453
1163
6151
2613
4991
3193
2323
2381
61
4005
5397
177
467
1685
2845
4817
931
5455
4179
3483
873
525
1917
1337
5919
5861
4759
4063
3657
3889
3773
3425
2439
3251
2207
5745
293
4643
5571
2671
2149
5049
1511
989
5339
4295
1743
3831
4701
5803

输出
25
回复

使用道具 举报

🔗
laoxie09 2015-6-30 11:59:57 | 只看该作者
全局:
darksteel 发表于 2011-7-29 13:11
不过我这个好像要升序的数组才行。。{:4_84:}

排序是0(nlogn)低于n^2完全可以先排序
回复

使用道具 举报

🔗
梦流星 2015-6-30 16:55:46 | 只看该作者
全局:


  1. #include <iostream>
  2. #include <algorithm>
  3. #include <cstdio>
  4. #include <cstdlib>
  5. #include <cstring>
  6. #include <unordered_map>
  7. #include <unordered_set>

  8. using namespace std;

  9. int n;
  10. int a[10001];

  11. //let's assume that sequence s(n) = a[i] s(n+1) = a[j]
  12. //dp_matrix[i][j] represent the count of sequence in s
  13. short int dp_matrix[10001][10001];

  14. int main()
  15. {
  16.     //cin >> n;
  17.     scanf("%d", &n);
  18.     for (int i = 0; i < n; ++i)
  19.         //cin >> a[i];
  20.         scanf("%d", &a[i]);
  21.     sort(&a[0], &a[n]);
  22.     unordered_map<int, int> element_map;
  23.     for (int i = 0; i < n; ++i)
  24.     {   
  25.         element_map[a[i]] = i;
  26.     }   
  27.     memset(dp_matrix, 0, sizeof(dp_matrix[0][0]) * 10001 * 10001);
  28.     short int max_len = 0;
  29.     const auto iter_end = element_map.end();

  30.     for (int i = 0; i < n; ++i)
  31.     {   
  32.         for (int j = i + 1; j < n; ++j)
  33.         {   
  34.             int cur_delta = a[j] - a[i];
  35.             int k_value = a[i] - cur_delta;
  36.             auto iter = element_map.find(k_value);
  37.             if (iter != iter_end)
  38.             {   
  39.                 dp_matrix[i][j] = dp_matrix[iter->second][i] + 1;
  40.             }   
  41.             else
  42.             {   
  43.                 dp_matrix[i][j] = 2;
  44.             }   
  45.             if (dp_matrix[i][j] > max_len)
  46.             {   
  47.                 max_len = dp_matrix[i][j];
  48.             }   
  49.         }   
  50.     }   
  51.     cout << max_len << endl;
  52.     return 0;
  53. }

复制代码
这个代码还是tle了  实在过不去了~~~~ 咋办?
回复

使用道具 举报

🔗
梦流星 2015-6-30 16:59:40 | 只看该作者
全局:
本帖最后由 梦流星 于 2015-6-30 17:33 编辑
laoxie09 发表于 2015-6-30 11:59
排序是0(nlogn)低于n^2完全可以先排序

甲骨文大大见信好,  我在http://www.1point3acres.com/bbs/ ... 8&page=1#pid1935366 发了个贴, 是关于求最长等数列的
我的代码目前的状态是tle  没有超时的case都是ac的
我能想到的优化方法都试过了, 但是还是差一点, 时间限制是2s, 我最长的case跑2500ms, 我不知道该从什么地方下手优化了.不知道您有没有什么好的建议?, 另附case:

case随附件附上, 太大了, 贴不上来
太大了贴不上来我也没找到怎么贴附件
(http:)

pan.baidu.com/s/1dDGrF6D


回复

使用道具 举报

🔗
梦流星 2015-6-30 20:29:49 | 只看该作者
全局:
已经AC了, 把自己的代码贴上来, 这个地方需要自己写个哈希, 系统自带的__gnu_cxx::hash_map要快于unordered_map, 但是还是tle,
自己写的则快很多:

  1. #include <iostream>
  2. #include <algorithm>
  3. #include <cstdio>
  4. #include <cstdlib>
  5. #include <cstring>
  6. #include <map>
  7. #include <unordered_map>
  8. #include <unordered_set>
  9. #include <ext/hash_map>

  10. using namespace std;
  11. using __gnu_cxx::hash_map;

  12. int n;
  13. int a[10001];

  14. const int BUCKET_SIZE   = 42839;
  15. const int NEXT_POS      = 7;

  16. typedef struct _my_hash
  17. {
  18.     int _bucket[BUCKET_SIZE];
  19.     int _key[BUCKET_SIZE];
  20.     _my_hash()
  21.     {
  22.         memset(_bucket, 0, sizeof(_bucket[0]) * BUCKET_SIZE);
  23.         memset(_key, 0, sizeof(_key[0]) * BUCKET_SIZE);
  24.     }
  25.     void insert(int key, int value)
  26.     {
  27.         int mod = key % BUCKET_SIZE;
  28.         while (_key[mod] != 0)
  29.         {
  30.             mod = (mod + NEXT_POS) % BUCKET_SIZE;
  31.         }
  32.         _bucket[mod]    = value;
  33.         _key[mod]       = key;
  34.     }
  35.     int find(int key)
  36.     {
  37.         int origin = key % BUCKET_SIZE;
  38.         int mod = key % BUCKET_SIZE;
  39.         while (_key[mod] != 0)
  40.         {
  41.             if (_key[mod] == key)
  42.             {
  43.                 return _bucket[mod];
  44.             }
  45.             mod = (mod + NEXT_POS) % BUCKET_SIZE;
  46.             if (mod == origin)
  47.             {
  48.                 return -1;
  49.             }
  50.         }
  51.         return -1;
  52.     }
  53. }my_hash_t;

  54. //let's assume that sequence s(n) = a[i] s(n+1) = a[j]
  55. //dp_matrix[i][j] represent the count of sequence in s
  56. short int dp_matrix[10001][10001];

  57. int main()
  58. {
  59.     //cin >> n;
  60.     scanf("%d", &n);
  61.     for (int i = 0; i < n; ++i)
  62.         //cin >> a[i];
  63.         scanf("%d", &a[i]);
  64.     sort(&a[0], &a[n]);
  65.     //unordered_map<int, int> element_map;
  66.     //map<int, int> element_map;
  67.     //hash_map<int, int> element_map(42839);
  68.     my_hash_t my_hash;
  69.     //hash_map<int, int> element_map;
  70.     for (int i = 0; i < n; ++i)
  71.     {
  72.         //element_map[a[i]] = i;
  73.         my_hash.insert(a[i], i);
  74.     }
  75.     memset(dp_matrix, 0, sizeof(dp_matrix[0][0]) * 10001 * 10001);
  76.     short int max_len = 0;
  77.     //const auto iter_end = element_map.end();

  78.     for (int i = 0; i < n; ++i)
  79.     {
  80.         for (int j = i + 1; j < n; ++j)
  81.         {
  82.             int cur_delta = a[j] - a[i];
  83.             int k_value = a[i] - cur_delta;
  84.             //auto iter = element_map.find(k_value);
  85.             //auto iter = element_map.end();
  86.             int ret = my_hash.find(k_value);
  87.             //if (iter != iter_end)
  88.             if (ret != -1)
  89.             {
  90.                 //dp_matrix[i][j] = dp_matrix[iter->second][i] + 1;
  91.                 dp_matrix[i][j] = dp_matrix[ret][i] + 1;
  92.             }
  93.             else
  94.             {
  95.                 dp_matrix[i][j] = 2;
  96.             }
  97.             if (dp_matrix[i][j] > max_len)
  98.             {
  99.                 max_len = dp_matrix[i][j];
  100.             }
  101.         }
  102.     }
  103.     cout << max_len << endl;
  104.     return 0;
  105. }
复制代码
回复

使用道具 举报

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

本版积分规则

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