众所周知,牛妹是一个offer收割姬,这次面试她遇到了这样的一个问题。
给了一个序列,让找出最长的“凸子序列”
何为“凸子序列”:数列中有一个xi,使得所有x0<x1<x2….xi-1<xi且xi>xi+1>xi+1>….>xn
eg:12345431,是山峰序列,12345234不是山峰序列
注:单调递增或单调递减序列也算山峰序列;单独一个数是长度为1的山峰序列
[1,2,3,6,1]
5
[1,2,2,1]
3
1,2,1
给定的序列中数都大于0 且不超过10000,且序列长度不超过1000
// 求两次最长上升子序列即可
int mountainSequence(vector<int>& numberList) {
vector<int> ans;
auto Find = [&](int l, int r, int key) ->int{
while (l < r) {
int mid = (l + r) >> 1;
if (ans[mid] > key) {
r = mid;
} else {
l = mid + 1;
}
}
return r;
};
auto __GetLen = [&] (vector<int>& tv) ->int {
ans.clear();
for (int i = 0; i < (int)tv.size(); i++) {
if (ans.empty()) {
ans.push_back(tv[i]);
} else {
int tmp = ans.back();
if (tmp < tv[i]) {
ans.push_back(tv[i]);
} else if (tmp > tv[i]) {
ans[Find(0, ans.size() - 1, tv[i])] = tv[i];
}
}
}
return (int)ans.size();
};
auto GetLen = [&](int mid) ->int {
int ret = 0;
vector<int> tv;
for (int i = 0; i < mid; i++) {
if (numberList[i] < numberList[mid]) {
tv.push_back(numberList[i]);
}
}
ret += __GetLen(tv);
tv.clear();
for (int i = mid + 1; i < (int)numberList.size(); i++) {
if (numberList[i] < numberList[mid]) {
tv.push_back(numberList[i]);
}
}
reverse(tv.begin(), tv.end());
ret += __GetLen(tv);
return ret + 1;
};
int Max = 0;
for (int i = 0; i < (int)numberList.size(); i++) {
Max = max(Max, GetLen(i));
}
return Max;
} 给定数组nums[N]
动态规划
dp[k][i]表示以第i个数为结尾的最大山峰子序列 ,k属于(0,1)表示当前数nums[i]是处于上升还是下降。shape(2,N)
初始化dp[0][0]=1,dp[1][0]=1
dp[0][i]=max(dp[0][p]) +1 p属于[0,i-1] 且nums[i]>nums[p]
dp[1][i]=max(dp[0][q],dp[0][q])+1 q属于[0,i-1] 且nums[i]<nums[p]
最后返回dp里的最大值即可
class Solution: def mountainSequence(self , numberList ): # write code here N = len(numberList) if N==1:return 1 dp = [[0]*N for i in range(2)] dp[0][0]=1 dp[1][0]=1 res = 0 for i in range(1,N): max0 = 0 max1 = 0 for j in range(i): if numberList[i]>numberList[j]: if dp[0][j]>max0: max0=dp[0][j] elif numberList[i]<numberList[j]: if dp[0][j]>max1: max1=dp[0][j] if dp[1][j]>max1: max1=dp[1][j] dp[0][i]=max0+1 dp[1][i]=max1+1 res = max(res,dp[0][i],dp[1][i]) return res
class Solution {
public:
/**
* 返回最大山峰序列长度
* @param numberList int整型vector 给定的序列
* @return int整型
*/
int mountainSequence(vector<int>& numberList) {
int Max = 0, n = numberList.size();
int dp1[n], dp2[n];
fill(dp1, dp1+n, 1);
fill(dp2, dp2+n, 1);
for(int i=1;i<n;i++)
for(int j=0;j<i;j++)
if(numberList[j]<numberList[i])
dp1[i] = max(dp1[i], dp1[j]+1);
for(int i=n-2;i>=0;i--)
for(int j=n-1;j>i;j--)
if(numberList[j]<numberList[i])
dp2[i] = max(dp2[i], dp2[j]+1);
for(int i=0;i<n;i++)
Max = max(Max, dp1[i]+dp2[i]-1);
return Max;
}
}; public int mountainSequence(int[] numberList) {
int len = numberList.length;
int[] left = new int[len];
int[] right = new int[len];
for (int i = 0; i < len; i++) {
left[i] = 1;
for (int j = 0; j < i; j++)
if (numberList[j] < numberList[i]) left[i] = Math.max(left[i], left[j] + 1);
}
for (int i = len - 1; i >= 0; i--) {
right[i] = 1;
for (int j = len - 1; j > i; j--)
if (numberList[j] < numberList[i]) right[i] = Math.max(right[i], right[j] + 1);
}
int max = 0;
for (int i = 0; i < len; i++) max = Math.max(max, left[i] + right[i] - 1);
return max;
} class Solution {
public:
/**
* 返回最大山峰序列长度
* @param numberList int整型vector 给定的序列
* @return int整型
*/
int mountainSequence(vector<int>& numberList) {
// write code here
int res = 0;
int n = numberList.size();
vector<int> dp1(n, 1), dp2(n, 1);
for(int i = 1; i < n; ++i)
for(int j = 0; j < i; ++j)
if(numberList[i] > numberList[j])
dp1[i] = max(dp1[i], dp1[j] + 1);
for(int i = n-2; i >= 0; --i)
for(int j = n-1; j > i; --j)
if(numberList[i] > numberList[j])
dp2[i] = max(dp2[i], dp2[j] + 1);
for(int i = 0; i < n; ++i)
res = max(res, dp1[i] + dp2[i] - 1);
return res;
}
}; class Solution {
public:
int mountainSequence(vector<int>& a) {
int n = a.size();
vector<int> dp1(n, 1), dp2(n, 1);
for(int i = 0; i < n; i++)
for(int j = 0; j < i; j++)
if(a[i] > a[j])
dp1[i] = max(dp1[i], dp1[j] + 1);
for(int i = n - 1; i >= 0; i--)
for(int j = n - 1; j > i; j--)
if(a[i] > a[j])
dp2[i] = max(dp2[i], dp2[j] + 1);
int res = 0;
for(int i = 0; i < n; i++)
res = max(res, dp1[i] + dp2[i] - 1);
return res;
}
}; class Solution {
public:
/**
* 返回最大山峰序列长度
* @param numberList int整型vector 给定的序列
* @return int整型
*/
int mountainSequence(vector<int>& numberList)
{
// write code here
int** pre, ** bac;
int max = 0;
if (numberList.size() == 0)
return 0;
pre = new int* [numberList.size()];
bac = new int* [numberList.size()];
for (int i = 0; i < numberList.size(); ++i)
{
//元素0长度,元素1最大值
pre[i] = new int[2];
bac[i] = new int[2];
}
pre[0][0] = 1;
pre[0][1] = numberList[0];
bac[numberList.size() - 1][0] = 1;
bac[numberList.size() - 1][1] = numberList[numberList.size() - 1];
//计算当前结点 左侧递增序列长度
for (int i = 1; i < numberList.size(); ++i)
{
pre[i][0] = 1;
pre[i][1] = numberList[i];
for (int j = 0; j < i; ++j)
{
if (pre[i][1] > pre[j][1] && pre[j][0] + 1 > pre[i][0])
{
pre[i][0] = pre[j][0] + 1;
}
}
}
//计算当前结点 右侧递减序列长度
for (int i = numberList.size() - 2; i >= 0; --i)
{
bac[i][0] = 1;
bac[i][1] = numberList[i];
for (int j = numberList.size() - 1; j > i; --j)
{
if (bac[i][1] > bac[j][1] && bac[j][0] + 1 > bac[i][0])
{
bac[i][0] = bac[j][0] + 1;
}
}
}
//计算最大值
for (int i = 0; i < numberList.size(); ++i)
{
if (pre[i][0] + bac[i][0] - 1 > max)
max = pre[i][0] + bac[i][0] - 1;
}
return max;
}
}; int mountainSequence(vector<int>& numberList) {
int len = numberList.size(),res = 0;
vector<int> dp1(len,1),dp2(len,1);
for(int i=1;i<len;i++){
for(int j=0;j<i;j++){
if(numberList[j]<numberList[i]){
dp1[i] = max(dp1[j]+1,dp1[i]);
}
if(numberList[len-1-j]<numberList[len-1-i]){
dp2[len-1-i] = max(dp2[len-1-i],dp2[len-1-j]+1);
}
}
}
for(int i=0;i<len;i++){
res = max(dp1[i]+dp2[i]-1,res);
}
return res;
} class Solution: def mountainSequence(self , numberList ): # write code here l2r, r2l = [1], [1] for i in range(1,len(numberList)): temp = 1 for j in range(len(l2r)): if numberList[i] > numberList[j]: temp = max(temp,l2r[j]+1) l2r.append(temp) for i in range(len(numberList)-2,-1,-1): temp = 1 for j in range(len(r2l)): if numberList[i] > numberList[-1-j]: temp = max(temp,r2l[j]+1) r2l.append(temp) result = 0 for i in range(len(l2r)): result = max(result, l2r[i] + r2l[-1-i] - 1) return result