leetcode 525. Contiguous Array

Given a binary array, find the maximum length of a contiguous subarray with equal number of 0 and 1.

Example 1:

Input: [0,1]
Output: 2
Explanation: [0, 1] is the longest contiguous subarray with equal number of 0 and 1.

 

Example 2:

Input: [0,1,0]
Output: 2
Explanation: [0, 1] (or [1, 0]) is a longest contiguous subarray with equal number of 0 and 1.

 

Note: The length of the given binary array will not exceed 50,000.

題目大意:給定一個二值數組,返回含有相同個數的0和1的最長連續子數組的長度。

方法一:暴力法(超時)


C++代碼

我們考慮所有的連續子數組,判斷0和1個數是否相同,如果相同,則與當前已找到的符合條件的連續子數組的長度進行比較。

 1  int findMaxLength(vector<int>& nums) {
 2         int sum = 0;
 3         int maxsize = 0;
 4         for (int i = 0; i < nums.size(); ++i) {
 5             sum = 0;
 6             for (int j = i; j < nums.size(); ++j) {
 7                 //計算[i,j]的和,[i, j]的和=[i,j-1]的和+j,所以可以利用前面得到的結果
 8                 (nums[j] == 1) ? (sum += 1) : (sum -= 1);
 9                 if (sum == 0 && (maxsize < j - i + 1)) {
10                     maxsize = j - i + 1;
11                 }
12             }
13         }
14         return maxsize;
15     }

在這裏,我們討論索引[i,j]中1和0的個數是否相等時,避免直接統計1和0的個數,而是利用累加和,是1則加1,0則減1,累加和爲0則代表1和0個數相同。

時間複雜度:$O(n^2)$

空間複雜度:$O(1)$


方法二:哈希表

假設S[i]表示數組索引爲0到i的子數組各元素之和(遇到1則加1,遇到0則減1),如果S[i]=0,那麼[0,i]組成的子數組是符合條件的;

假如S[i] !=0 且 S[i] = m,然而存在最小的$j \in [0,i)$使得S[j] = m,那麼[j+1, i]是符合條件的連續子數組。因爲S[i]=S[j],我們要根據累加和m,得到索引j,所以需要建立累加和映射到索引的哈希表。

累加和的取值範圍爲[-n, n](n爲數組的長度,-n時表示數組全爲-1, n時表示數組全爲1),所以開闢一個2n+1的數組。

 1 int findMaxLength(vector<int>& nums) {
 2         int len = nums.size();
 3         vector<int> index(2 * len + 1, -2); //初始化爲-2表示這些累加和尚未出現
 4         index[len] = -1; //一開始累加和爲0,索引爲-1
 5         int maxlen = 0, sum = 0;
 6         for (int i = 0; i < nums.size(); ++i) {
 7             sum += (nums[i] == 0) ? -1 : 1;
 8             if (index[sum + len] >= -1) { //如果當前累加和已經出現過,則比較大小並更新maxlen,這裏就不用更新累加和對應的索引
 9                 maxlen = max(maxlen, i - index[sum + len]);
10             } else { //否則記錄累加和對應的索引
11                 index[sum + len] = i;
12             }
13         }
14         return maxlen;
15     }

需要注意的是,累加和爲m可能對應多個索引,因爲要找最長的連續子數組,所以我們只能保存最小的索引。

時間複雜度:$O(n)$

空間複雜度:$O(n)$

或者利用STL map數據結構:

 1 int findMaxLength(vector<int>& nums) {
 2         int len = nums.size();
 3         unordered_map<int, int> hM;
 4         int maxlen = 0, sum = 0;
 5         for (int i = 0; i < nums.size(); ++i) {
 6             sum += (nums[i] == 0) ? -1 : 1;
 7             if (sum == 0)
 8                 maxlen = i + 1;
 9             if (hM.find(sum + len) != hM.end()) { 
10                 maxlen = max(maxlen, i - hM[sum + len]);
11             } else {
12                 hM[sum + len] = i;
13             }
14         }
15         return maxlen;
16     }

 


 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章