一开始很天真的想法,从左或者右边找多出来的数字,删除多出来的数字,但是在[0,1,1,0,1,1,1,0]样例上粗错了。果然这种想法是有问题的。上述样例最大的subarray是[0,1,1,0],但是按照我的直观算法,第一次操作删除2个1,由左边删除更快,因此删完后为[0,1,1,1,0],再操作就不会得到[0,1,1,0]这个答案了。
class Solution { public: int findMaxLength(vector<int>& nums) { int left=0; int right=nums.size()-1; map<int,int> count; for(int i=0;i<nums.size();i++) count[nums[i]]++; if(max(count[0],count[1])==0) return 0; while((count[0]!=count[1])&&(min(count[0],count[1])!=0)) { int num; int time; num=count[0]>count[1]?0:1; time=abs(count[0]-count[1]); int temp1=left; int count1=0; while(1) { if(nums[temp1]==num) count1++; if(count1==time) break; temp1++; } int temp2=right; int count2=0; while(1) { if(nums[temp2]==num) count2++; if(count2==time) break; temp2--; } //cout<<temp1<<" "<<temp2<<endl; if(temp1-left>right-temp2) { count[num]-=time; count[1-num]-=right-temp2+1-time; right=temp2-1; } else { count[num]-=time; count[1-num]-=temp1-left+1-time; left=temp1+1; } } return 2*min(count[0],count[1]); } };参考了discuss的思路,参照它的思路写出自己的代码。结果代码超时了。看来要进一步加快处理速度,要引入hashmap了。
class Solution { public: int findMaxLength(vector<int>& nums) { int sum=0; int maxLength=0; if(nums.size()<2) return maxLength; vector<int> func(nums.size()+1,0);//index->sum for(int i=0;i<nums.size();i++) { if(nums[i]==0) sum+=-1; else sum+=1; func[i+1]=sum; //cout<<func[i+1]<<endl; for(int j=0;j<i+1;j++) { if(func[i+1]-func[j]==0) maxLength=max(maxLength,i-j+1); } } return maxLength; } };经一步修改,建立一个sum到index的映射函数func,它只存储最远处的sum,如果该sum存在,那么计算区间长度,否则就把该sum存入函数。 最终AC代码为
class Solution { public: int findMaxLength(vector<int>& nums) { int sum=0; int maxLength=0; if(nums.size()<2) return maxLength; map<int,int> func; func[0]=0; for(int i=1;i<=nums.size();i++) { if(nums[i-1]==0) sum+=-1; else sum+=1; if(func.count(sum)==0) func[sum]=i; else maxLength=max(maxLength,i-func[sum]); } return maxLength; } };