三種演算法求乙個數字序列的最長遞增子串行

2021-07-30 15:55:24 字數 2451 閱讀 8753

也有很多部落格寫如何實現最長遞增子串行的演算法,自己查閱了一些資料總結出三種實現的演算法,兩種是常見的處理思路,還有一種是本人自己想出來的演算法,很好理解,但是效率不是特別高。

演算法一:

將n個數的原序列a[n]排序後得到遞增序列b[n],則把求a的最長單調遞增子串行問題轉化成求a、b序列的最長公共子串行(lcs)。

這個演算法是演算法導論書後面習題的標準答案解法了,有很多人寫過實現。時間複雜度o(n^2)。

#include#include#include#include#include#include#include#include using namespace std;

/*方法1:將這n個數的序列排序之後,將最長遞增子串行轉變為lcs*/

int main()

sort(b, b + n);

int i, j, cnt = 0;

for (i = 1; i <= n; i++)

} //輸出任意乙個最長公共子串行,倒敘遍歷len陣列

for (i = n, j = n; i > 0 && j > 0;)

else if(len[i][j] == len[i][j-1])

else

}

printf("%d\n%d", cnt, res[cnt-1]);//輸出這個最長公共子串行。

for (i = cnt - 2; i >= 0; i--) printf(" %d", res[i]);

printf("\n");

} return 0;

}

注意:這種求法在輸入序列中元素各不相同是可行的,一旦a中有重複元素,單純的將a sort一下是不可以的,這時候要先去重再排序得到b序列。

演算法二:

因為自己正在學dp,所以一開始是嘗試使用dp的思想做的,時間複雜度也是o(n^2)。以dp[i]表示以i位結尾的最長遞增子串行的長度。那麼dp[i] = max(dp[i], dp[j]+1), j = 1, 2, 3,...,i-1。對於每個j

#include#include#include#include#include#include#include#include using namespace std;

/*輸出最長遞增子串行*/

/*方法2:n^2複雜度,dp*/

int main()

dp[0] = 1;

res[0] = 0;

for (int i = 1; i < n; i++)

}if(dp[i] == 1) res[i] = i;

} //遍歷得到最長的遞增子串行的長度以及結尾的位數

int maxlen = dp[0], maxloc = 0;

for(int i = 1; i < n; i++)

} //printf("%d\n",maxlen);

//遍歷res陣列,將這個最長遞增子串行儲存並輸出

int cnt = 0;

ans[cnt++] = num[maxloc];

while (res[maxloc] != maxloc)

for (int i = cnt - 1; i > 0; i--)

printf("%d\n", ans[0]);

} return 0;

}

演算法三:

這個演算法是效率比較高的dp求解。時間複雜度是o(nlgn)。關鍵是要抓住乙個長度位i的候選子串行的尾元素至少不比乙個長度為i-1的候選子串行的尾元素小。這是因為長度為i的候菜單調遞增子串行一定是從某個長度為i-1的候菜單調遞增子串行再加乙個尾元素得到的,以l[i]表示長度為i的候選子串行的尾元素,則有l[1]<=l[2]<=l[3]<=...<=l[m],m為最長候選子串行長度。

#include#include#include#include#include#include#include#include using namespace std;

/*方法3:nlgn複雜度。乙個長度為i的尾元素至少不比乙個長度為i-1的尾元素小。*/

int main()

l[0] = num[0];

m[0] = 0;

prel[0] = -1;

len = 1;

for (i = 1; i < n; i++)

//for (i = 0; i < len; i++) printf("%d ", l[i]);

pos = m[len-1];

for (i = len - 1; i >= 0 && pos != -1; i--)

//輸出

for (i = 0; i < len - 1; i++)

printf("%d\n", res[len-1]);

} return 0;

}

判斷乙個數字序列是BST後序遍歷的結果

相傳此乃網易二面題 要求現場手寫 判斷乙個數字序列是bst後序遍歷的結果。如圖所示 對於後續遍歷的排序二叉樹應具有上面的乙個不等式性質 以及 根節點為最後乙個節點的性質 因此 如下 序列array有n個元素 如果這n個元素是二叉排序樹的後續遍歷結果 返回true 否則 返回false bool is...

求乙個陣列的最長連續子串行

分析 如果允許o nlogn 的複雜度,那麼可以先排序,可是本題要求o n 由於序列裡的元素是無序的,又要求o n 首先要想到用雜湊表。用乙個雜湊表unordered mapused 記錄每個元素是否使用,對每個元素,以該元素為中心,往左右擴張,直到不連續為止,記錄下最長的長度。class solu...

求乙個陣列的最長遞減子串行

其實這個題目和求最長遞增子串行的題目是乙個思想,就是用dp做 如下 dp5.cpp 定義控制台應用程式的入口點。include stdafx.h include using namespace std const int max 1000 int dp max int data max 找到最長遞增...