给定一个由 0 和 1 组成的数组 arr ,将数组分成 3 个非空的部分 ,使得所有这些部分表示相同的二进制值。
如果可以做到,请返回任何 [i, j],其中 i+1 < j
如果无法做到,就返回 [-1, -1]。
注意,在考虑每个部分所表示的二进制时,应当将其看作一个整体。例如,[1,1,0] 表示十进制中的 6,而不会是 3。此外,前导零也是被允许的,所以 [0,1,1] 和 [1,1] 表示相同的值。
思路:如果可以分成三部分,那三部分1的数量必然相等,意味着1的总数可以被3整除。判断完可以被整除以后,下一步找到每部分的第一个1的位置,从这个位置开始遍历对比三部分是否都相等。如果都相等,那第三部分遍历到最后的下标一定是n-1。
class Solution {
public:
vector<int> threeEqualParts(vector<int>& arr) {
int n=arr.size();//数组长度
int cnt=accumulate(arr.begin(), arr.end(),0);//(起始位置,结束位置,初始值)
if(cnt%3)return{-1,-1};//1的数量不是3的整数倍,不成立
if(!cnt)return{0,2};//1的数量为0
cnt/=3;
//找到三个组的第一个1的位置
int i=find_f1(1,n,arr),j=find_f1(cnt+1,n,arr),k=find_f1(2*cnt+1,n,arr);
//从第一个1的位置开始遍历,如果三组的成分一致,那k必然等于n
for(;k<n&&arr[i]==arr[j]&&arr[j]==arr[k];++i,++j,++k){}
return k == n ? vector<int>{i - 1, j} : vector<int>{-1, -1};
}
private:
int find_f1(int x,int n,vector<int>& arr){
int s=0;
for(int i=0;i<n;i++){
s+=arr[i];
if(s==x)return i;
}
return 0;
}
};