最長的含有相同數目的01子串 括號匹配問題

2021-06-16 19:15:13 字數 1558 閱讀 9355

題目:給定乙個字串,字串中只包含『0』和『1』。請找到乙個最長的子串,使得其中0和1的數量是相同的

例1:「10101010」 結果就是其本身

例2:「0011110」結果是「0011」

擴充套件:給定乙個字串,字串只包含『(』和『)』,請找出乙個最長的子串,使得該子串滿足括號匹配法則。

例1:「(()())()()」結果為自身

例2:「())()()(」結果為「()()"

錯誤的解法:(沒考慮仔細)

解:擴充套件後題目要求更嚴格一點,但解題思路是一樣的:

用棧儲存字元,掃瞄字串,如果

1)當前字元與棧頂匹配(『0』和『1』相互匹配,『)』與『(』匹配),刪除棧頂,計算長度,遍歷下乙個字元。

2)當前字元與棧頂不匹配,當前字元入棧,遍歷下乙個字元。

**1:與講解稍有不同,棧記憶體的是下標不是字元,這樣方便計算長度。

時間複雜度:o(n),空間複雜度:最壞為o(n)

#include #include #include using namespace std;

void longestsubsequence(const string &str, int &s, int &t)

若找不到滿足條件的j,則f[i] = 0;

最後的結果為 max。

此演算法時間複雜度為o(n^2),空間複雜度o(n),同時適用原問題和擴充套件問題。

解法ii:對解法i進行優化:

由於解法i需要遍歷找j,所以時間複雜度比較高。

實際上,可以根據01串的特點,在o(1)的時間確定出j。

掃瞄字串,將掃瞄到的0的個數與1的個數的差,記錄在a陣列中,則a[i]值在區間[-n, n],n為總的字元個數。

狀態轉移方程可改寫為:

f[i] = f[j] + (i - j), 其中j為max。

如果在算f的時候,同時記錄陣列b,b[k]表示差值為k的最後出現的位置,注意此處k理論上可以為負值,那麼狀態轉移方程可以改寫為:

f[i] = f[j] + (i - j), 其中j=b[a[i]]。

此演算法,時間複雜度o(n),空間複雜度3 * o(n)。 僅適用於原問題。

解法iii:對解法ii進行 簡化:

仔細觀察會發現,f[i]的值等於:差值a[i]最早出現的位置,與i的距離。所以可以對解法ii進行簡化,見**2

此演算法,時間複雜度與解法ii一樣,同為o(n),空間複雜度同為o(n),但係數變小了2 * o(n)。 僅適用於原問題。

**2:

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

void longestsubsequence(const string &str, int &s, int &t){

int strlen = str.size();

vectorv(strlen * 2 + 1, -1);

int maxlen = 0;

int diff = 0;

for(int i = 0; i

詳解opencv的HOG描述子維度數目的計算原理

opencv的hog描述子與sift surf orb描述子一樣,都是屬於同一型別的描述符,這種描述符可以作為svm ann的模型輸入資料。如何更科學的使用hog描述符,主要取決於hog的引數是如何轉為維度數目的。下面是python 對乙個影象為40x40大小生成hog描述子的過程。import c...

尋找最長不含有重複字元的子串

變數 開始索引 map 字元 索引 最大長度 如果碰到map已經存在該字元的並且出現位置 開始索引,將map中記錄的位置的下乙個位置當做開始索引 如果當前不重複區間大於記錄最大長度儲存到最大長度 將當前遍歷到的字元索引儲存到map byte int中,byte存放字元 int存放索引 package...

C 生成指定數目的互不相同的隨機數

dotnet.frameword中提供了乙個專門產生隨機數的類system.random,計算機並不能產生完全隨機的數字,它生成的數字被稱為偽隨機數,它是以相同的概率從一組有限的數字中選取的,所選的數字並不具有完全的隨機性,但就實用而言,其隨機程度已經足夠了。在使用隨機數時,要先初始化乙個隨機數發生...