日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

最长等差数列

發布時間:2024/9/30 编程问答 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 最长等差数列 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

http://haixiaoyang.wordpress.com/category/dynamic-programming/

http://www.51nod.com/question/index.html#!questionId=79

在一個升序排列好的數列里面找到最長的等差數列

例子:1 3 5 6 8 9 10 12 13 14
子數列有(兩項的不在列舉)
1 3 5
1 5 9 13
3 6 9 12
3 8 13
5 9 13
.....

得出的最長的等差數列應該是:6 8 10 12 14


方案1:

用hash


遍歷所有可能的差值d

? ?hash表中記錄的是到當前為止,以之前的數字為結尾的等差數列的最長長度

? ?對一個新的元素,將其減去d之后,查找是否有相同的值,如果存在,則替換為這個新元素,并將值加1

public static void Solve1(int[] items) {Dictionary hash = new Dictionary();int max = items.Max() - items.Min();int maxLength = 2, maxInc = -1, last = -1;for (int inc = 1; inc < max; inc++){if (inc * maxLength > max)break;hash.Clear();hash.Add(items[0], 1);for (int i = 1; i < items.Length; i++){if (hash.ContainsKey(items[i] - inc)){int value = hash[items[i] - inc];hash.Remove(items[i] - inc);hash.Add(items[i], value + 1);if (value + 1 > maxLength){maxLength = value + 1;maxInc = inc;last = items[i];}}else if (!hash.ContainsKey(items[i]))hash.Add(items[i], 1);}}Console.WriteLine("{0} {1} {2}", maxLength, maxInc, last); }
方法2:

//Find the length of the longest arithmetic progression sequence of a sorted array//solution: //suppose there is the array a[n] with arithmetic progression: // ... a[i], a[j], a[k], use A[i][j] to symbol the number of arithmetic progression //starting from a[i], a[j], then A[i][j] = 1 + A[j][k], in which case //a[j] - a[i] == a[k] - a[j]; since the array is sorted, from each possible //middle point j, we can extend on left and right to seek out all pairs that make //a[i] - a[left] == a[right] - a[i]const int M = 15; int GetLPS(int a[M]) {assert(a);if (1 == M) return 1;int rec[M][M];for (int i =0; i < M; i++)for (int j = 0; j < M; j++)rec[i][j] = 2;int nMax = 2;for (int i = M - 2; i >= 1; i--){int nLft = i - 1;int nRgt = i + 1;while (nLft >= 0 && nRgt < M){if (a[i] - a[nLft] == a[nRgt] - a[i]){//one thing is if you iterate from left to right,//you should assign to rec[i][nRgt] rather than rec[nLft][i]rec[nLft][i] = rec[i][nRgt] + 1;if (rec[nLft][i] > nMax)nMax = rec[nLft][i];//well, the continuous same elements don't affect the result//why???nLft--, nRgt++; }else if (a[i] - a[nLft] < a[nRgt] - a[i])nLft--;else nRgt++;}}return nMax; }

設下標 j < i < k

f[i,k]表示以a[i], a[k]為等差數列的最后兩項的最長長度

如果 a[i]-a[j] = a[k] - a[i]則 f[i,k] = f[j,i] +1


int maxDiffLen(int *a, int n) {vector<vector<int> > vt(n);for (int i = 0; i < n; ++i)vt[i].resize(n , 2 );int maxLen = 0;for (int i = 1; i < n - 1 ; ++i ) {int j = i - 1;int k = i + 1;while (j >= 0 && k < n) {if (a[k] - a[i] > a[i] - a[j]) --j;else if ( a[k] - a[i] < a[i] - a[j] ) ++k;else {vt[i][k] = vt[j][i] + 1;if (vt[i][k] > maxLen)maxLen = vt[i][k];++k;--j;}}} return maxLen;}

又想到一種方法,但是很占內存。f[i][k]表示以a[i]結尾的,差為k的數列的最大長度。


int getLArray(int *a, int n) {int maxDiff = a[n-1] - a[0];int ** f = new int *[n];for (int i = 0; i < n ; ++i)f[i] = new int [maxDiff+1];for (int i = 0; i < n ; ++i)for (int j = 0; j <= maxDiff; ++j)f[i][j] = 1;int maxLen = 2;for (int i = 1; i < n; ++i) {for (int j = i - 1; j >=0; --j) {int k = a[i] - a[j];if (f[i][k] < f[j][k] + 1)f[i][k] = f[j][k] + 1;if (maxLen < f[i][k])maxLen = f[i][k];}}for (int i = 0; i < n; ++i)delete [] f[i];delete []f;return maxLen; }

總結

以上是生活随笔為你收集整理的最长等差数列的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。