本文最后更新于 142 天前。
要使分成三段后,每段二进制数都相等,就是要每段去除前导零后剩下的二进制部分相同,这是题目直接翻译过来,要完成的约束条件。
将条件放宽一点,要实现就更容易,去除前导零后剩下的二进制部分相同,起码要保证每段中1的个数相同,原始数组中可以很容易地统计出1的个数sum,如果sum/3可以整除,继续往下做,如果不能整除,一定无解,输出[-1, -1]。
求出每段中1的个数num = sum / 3,例如sum = 9,num = 3,因此第一个1,第二个1,第三个1,属于第一段,第四个1,第五个1,第六个1属于第二段,第7个1,第八个1,第九个1属于第三段,其中第三段的后缀部分是可以确定的,从第7个1一直到数组末尾是第三段的后缀部分,后缀部分长度len。
1的个数一样了,数值部分长度也需要一样,因此从第一段第一个1开始,长len的部分,是第一段后缀部分(如果已经超出第一段的部分进入第二段,这时也无解,输出[-1, -1]),从第二段第一个1开始,长len的部分,是第二段后缀部分(如果已经超出第二段的部分进入第三段,这时也无解,输出[-1, -1]),这样得到了三段的数值部分,比较是否相同,如果相同,输出[第一段末尾的下标,第二段末尾的下标 + 1],否则输出[-1, -1]。
特殊情况sum = 0,输出[0, 2]。
class Solution {
public:
vector<int> threeEqualParts(vector<int>& arr) {
int len = arr.size();
int sum = 0;
int num = 0;
vector<int> ans;
for(int i = 0;i<len;i++){
if(arr[i] == 1){
sum++;
}
}
if(sum % 3 != 0){
ans.push_back(-1),ans.push_back(-1);
return ans;
}
if(sum == 0){
ans.push_back(0),ans.push_back(2);
return ans;
}
num = sum / 3;
int cnt = 0;
vector<int> pos;
for(int i = 0;i<len;i++){
if(arr[i] == 1){
cnt ++;
if(cnt == 1) {
pos.push_back(i);
}
if(cnt == num){
cnt = 0;
}
}
}
len = len - pos[2];
bool flag = true;
for(int i = pos[0],j = pos[2];i - pos[0] + 1 <= len;i++,j++){
if(arr[i] != arr[j]){
flag = false;
break;
}
}
for(int i = pos[1],j = pos[2];i - pos[1] + 1 <= len;i++,j++){
if(arr[i] != arr[j]){
flag = false;
break;
}
}
if(flag){
ans.push_back(pos[0] + len - 1),ans.push_back(pos[1] + len);
return ans;
}
else{
ans.push_back(-1),ans.push_back(-1);
return ans;
}
}
};