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