1. 程式人生 > >leetcode--hash--Contiguous Array

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; }