leetcode--hash--Contiguous Array
題目描述:Given a binary array, find the maximum length of a contiguous subarray with equal number of 0 and 1.
Note: The length of the given binary array will not exceed 50,000.
思路,參考官網,將陣列中的 0 全都轉化為 -1,然後遍歷陣列求和sum:如果遍歷到下標a時的sum=K,繼續遍歷到下標b時的sum還是sum=K,(a<b),那麼可以得出(a~b] 的陣列滿足要求。即得出結果是 result = b - a;這是這個演算法的數學推論。
//方法一,用map結構,因為map的實現是樹形資料結構,每次 .find 都需要花費 log(n)的時間,所以要比第二種方法慢。
int findMaxLength(vector<int>& nums) { int result = 0, sum = 0; for (int i = 0; i < nums.size(); i++) if (nums[i] == 0) nums[i] = -1;
map<int, int> m; m[0] = -1; //這個是必須的初始條件。考慮 0,1 的場景 for (int i = 0; i < nums.size(); i++) { sum += nums[i]; if (m.find(sum) != m.end()){ //注意,找到了重複的sum,只是更新result,並不對m[sum]做更新 result = max(result, i - m[sum]); }else{ m[sum] = i; //在相同的幾個sum中,m[sum]總是儲存的是最開始的那個下標值 } } return result; }
//方法二,直接用陣列儲存值。雖然花費了更多的空間,但這個方法測試比方法一快一倍!
int findMaxLength(vector<int>& nums) { int result = 0; int sum = 0;
//初始化陣列 int size = 2*nums.size() + 1; vector<int> vec; for(int i=0; i<size; ++i) { vec.push_back(-2); } vec[0] = -1; //注意vec[0] = -1 必須初始化為 -1 //遍歷陣列,記錄當前的陣列和sum,查hash表, //如果sum對應的值不為空(-2),那麼sum值出現過,用當前的下標減去sum值對應的下標方式求結果。 //如果sum對應的值為空(-2),那麼該值沒有出現過,需要儲存當前sum的下標值 int sumTmp = 0; for(int i=0;i<nums.size();++i) { if(0==nums[i]) { sum -= 1; }else{ sum += 1; } //雜湊轉換,sum<0時取反,在加上vec的size大小(sum為負值時用vec[n+1~2n]) if(sum<0){ sumTmp = (nums.size() - sum); }else{ sumTmp = sum; }
//assert(sumTmp<size); //證明sumTmp不越界訪問 if(-2 != vec[sumTmp]) //有記錄則更新結果 { result = max(result, i - vec[sumTmp]); }else{ //沒有記錄則更新 vec[sumTmp] = i; } } return result; }