思路:
这道题需要找规律了,因为题目是求有多少种方案获得平衡数组,那么就需要遍历所有元素。
首先 对于删除元素的左侧是可以发现不受影响的,但删除元素的右侧元素下标会-1,整体向左侧移动一个单位,那么原来在奇数位置的元素就会变到偶数位。所以我们只需要得到右侧的元素的和即可。
我们定义
int left_odd=0,right_odd=0;
int left_even=0,right_even=0;
int sum_odd=0,sum_even=0;
首先我们计算数组的奇数和 与 偶数和,然后遍历数组,从第一个元素开始,先判断是否处于第一个元素,如果是那么就不更新left_odd和left_odd,因为第一个元素左侧没有元素。如果不是就判断i-1的位置是偶数位还是奇数位,偶数位就给left_even相加,奇数就给left_odd加。这里也有一个知识点,这样积累前面数的和的为前缀和,也是一种算法。
我们已经知道删除元素右侧的奇偶位会交换,那么可以得到 一个结论,sum_odd-left_odd = right_even,因为在删除这个元素之前,等式左侧会得到右侧元素的奇数和,当删除元素后,下标向左移动,奇数和就变成了偶数和。同样 sum_even-left_even = right_odd。
接着在判断删除元素的位置是偶数还是奇数位,如果是偶数位,那么就应该right_odd减这个元素,因为这个元素本来就是偶数和里面的,然后right_odd是由总的偶数和减去左侧偶数和得到的,所以这个元素将会存在与right_odd中。
对于奇数位也是相同的。
最后在判断left_odd+right_odd 是否等于 left_even+right_even,相等就计数一次。
代码:
class Solution {
public:
int waysToMakeFair(vector<int>& nums) {
int n=nums.size();
int left_odd=0,right_odd=0;
int left_even=0,right_even=0;
int sum_odd=0,sum_even=0;
int cnt=0;
for(int i=0;i<n;++i){
if(i%2==0) sum_even+=nums[i];
else sum_odd += nums[i];
}
for(int i=0;i<n;++i){
if(i!=0){
if((i-1)%2==0) left_even+=nums[i-1];
else left_odd+=nums[i-1];
}
right_even = sum_odd - left_odd;
right_odd = sum_even -left_even;
if(i%2==0){
right_odd-=nums[i];
}
else{
right_even-=nums[i];
}
if(right_even+left_even==left_odd+right_odd) cnt++;
}
return cnt;
}
};