題目描述:
已知乙個長度為n的字串,只由0和1組成, 求乙個最長的子串,要求該子串出0和1出現的次數相等。
要求演算法時間複雜度盡可能的低。
比如: 1000010111000001,加粗的部分有4個0、4個1
思路:(1) 最簡單的想法就是遍歷所有的子串,之後判斷該子串是否滿足條件
n^2子串,每個子串掃一遍判斷0、1是否出現的次數相等,複雜度為o(n^3)
稍加思考就會發現, 如果乙個長度為n的子串滿足條件,加麼這n個元素的和 加起來一定=(n/2)
這樣在迴圈的過程中,增量加就可以了,不需要每個子串從頭計算,複雜度降為o(n^2);
偽碼:輸入 a[n]
int maxlen = 0, sum = 0, currlen = 0;
for(int i = 0; i
(2) 還有沒有辦法進一步降低演算法的複雜度呢?
問了一下姚神,得到了這樣一種巧妙的解法:定義乙個資料b[n], b[i]表示從a[0...i]中 num_of_0 - num_of_1,0的個數與1的個數的差
那麼如果a[i] ~ a[j]是符合條件的子串,一定有 b[i] == b[j],因為中間的部分0、1個數相等,相減等於0。 只需要掃一遍a[n]就能把b[n]構造出來了。
這樣問題就轉換成了求 距離最遠的一對數,使得b[i] == b[j],因為b[i]的範圍一定是[-n,n],-n到n的範圍都存起來,這樣每掃到b[i],查數就行了。
其實**真的非常簡單,乙個迴圈就搞定了,這就是演算法和思考的樂趣:)
int a[n],b[n];
int num[2*n + 1];
int count[2] = , maxlen = 0, currlen = 0;
memset(c, 2*n, -1);
for(int i = 0; i
藍橋 01字串
include defint max 5 int f max int main if i j f j 1 for k 1 k 5 k printf d n a k for i 1 i 5 i include int a 32 int min 1 int b 34 int main for i 0 i...
0 1字串問題
程式設計找出符合下列條件的字串 字串中僅包含0和1兩個字元 字串的長度為n 字串中不含有三個連續的相同子串。輸入檔案僅包含乙個整數n 0 n 35 表示字串的長度。輸出檔案僅包含乙個整數,表示符合上述條件的字串的總數。24 include include includeusing namespace...
01 字串反轉
result s 1 li b c f 4,5,6 a list reversed li print a 輸出 6,5,4,f c b result reduce lambda x,y y x,s 不認識,先記著 def func s 此處使用遞迴,不斷把第乙個字元,通過拼接的方式加到分片字串後面,...