每日一題 79 求陣列中最長遞增子串行

2021-06-18 00:40:45 字數 1808 閱讀 1472

題目來自程式設計之美 題目

思路(1) 動態規劃(複雜度為n^2)

方程:f[i]:表示以narr[i]為結尾的最長遞增子串行的最大長度。

f[i] = max(f[j]) + 1 && a[i] > a[j] && i > j;

方程的直觀含義:檢查

narr[i]能接在哪乙個數的後面。

如果要求lis序列,需要令開闢乙個陣列。

複雜度:o(n^2)

**:只求lis的長度

#include #include using namespace std;

/*f[i]:表示以narr[i]為結尾的最長遞增子串行的長度

f[i] = max(f[j]) + 1 && a[i] > a[j] && i > j;

f[i] = 1

*/int lis(int narr,int nlen)

} nmaxlen = max(nmaxlen,f[i]);

} //輸出

return nmaxlen;

}int main()

; cout<

#include #include using namespace std;

void print(int* narr,int* pre,int ncurpos)

print(narr,pre,pre[ncurpos]);

cout j;

f[i] = 1

*/int lis(int narr,int nlen)

}} if (nmaxlen < f[i])

}//輸出

print(narr,pre,nmaxpos);

cout思路(2)o(nlogn)的演算法

思路:陣列narrincr中的資料都是不重複的。

**:int binsearch(int narrincr,int nnum,int nstart,int nend)

else if (narrincr[nmid] > nnum)

else

}return nstart; //返回第乙個大於nnum的位置

}int lis(int narr,int nlen)

else

}return nend + 1;

}

利用stl,給出乙個更簡潔的**:

int lis(int narr,int nlen)

else

}return nend + 1;

}

注:

lower_bound作用:

在區間[

first,last

)

進行二分查詢,返回第乙個大於或等於val的元素位置(迭代器)。

(1)如果所有元素都小於val,則返回last的位置,且last的位置是越界的

(2)標頭檔案:#include

輸出乙個lis,複雜度為o(n) **

#include #include #include using namespace std;

void print(int narr,int ncurlen,int ncurpos,int narrpos)

if (ncurlen == narrpos[ncurpos])

else

}//輸出資訊

cout<

求陣列中最長遞增子串行

原文見 分析過程很清楚。這裡主要是 部分有改動。完全用c寫的,從檔案中讀入。另外,解法二的程式加了去重,求的是最長單調遞增子串行。求陣列中最長遞增子串行 寫乙個時間複雜度盡可能低的程式,求乙個一維陣列 n個元素 中的最長遞增子串行的長度。例如 在序列1,1,2,3,4,5,6,7中,其最長的遞增子串...

求陣列中最長遞增子串行

最長遞增子串行,longest increasing subsequence 下面我們簡記為 lis。排序 lcs演算法 以及 dp演算法就忽略了,這兩個太容易理解了。假設存在乙個序列d 1.9 2 1 5 3 6 4 8 9 7,可以看出來它的lis長度為5。下面一步一步試著找出它。我們定義乙個序...

求陣列中最長遞增子串行

根據 程式設計之美 中解法二的思路,發現記錄lis陣列是不必要的,只要直接不斷更新maxv即可。在遍歷整個陣列arr的過程中,maxv陣列的長度也在不斷增加。當遍歷到arr i 時,maxv j 中已經記錄了由arr 0 arr i 的序列可以得到的所有長度為j的子串行中最大元素的最小值。例如 ar...