面試題:給定一個數組,陣列中只包含0和1。請找到一個最長的子序列,其中0和1的數量是相同的
阿新 • • 發佈:2019-01-31
這個題目,看起來比較簡單,一些同學可能認為題目的描述符合動態規劃的特徵,然後就開始用動態規劃解,努力找狀態轉移方程。這些同學的感覺,是很正確的。但,找狀態轉移方程,我們要對原來的陣列進行變換一下。
原來是0和1的串,我們將0都換為-1。這樣題目目標就變成,找到一個最長的子串,子串數字和是0。設原陣列為A, DP[i]表示從0開始到i的子陣列和。DP遍歷一遍陣列即可。例1中的陣列產生的DP為:
0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
1 | 0 | 1 | 0 | 1 | 0 | 1 | 0 |
這個例子,最後一個值是0,並且長度是偶數位。直接滿足了結果。
再看例子2:
0 | 1 | 2 | 3 | 4 | 5 | 6 |
1 | 2 | 1 | 2 | 1 | 0 | -1 |
5的位置為0,最長子串從0開始到5,長度為6。
上面這兩個例子,所求的子串都是從頭開始,如果不是從頭開始,會是什麼樣的呢?看這個例子:1101100
0 | 1 | 2 | 3 | 4 | 5 | 6 |
1 | 2 | 1 | 2 | 3 | 2 | 1 |
通過觀察上面的表格,我們可以得到,DP[0]==DP[6]==DP[2],DP[1]==DP[3]. 根據DP的定義,如果DP[i]==DP[j],i 一種方法,我們用map儲存DP的值到位置的對映,如下表:
DP值 | 位置 | 最大位置 | 最小位置 | 最大長度 |
1 | 0,2,6 | 6 | 0 | 6 |
2 | 1,3 | 3 | 1 | 2 |
3 | 4 | 4 | 4 | 0 |
最長子串長度 | 6 |
我們最終的演算法,要綜合考慮最常穿是否從頭開始的。 上面的這個思路,時間複雜度是O(n),空間複雜度也是O(n).