一、题目
给你一个整数数组 nums。你需要选择恰好一个下标(下标从0开始)并删除对应的元素。请注意剩下元素的下标可能会因为删除操作而发生改变。
比方说,如果 nums = [6,1,7,4,1] ,那么:
选择删除下标 1 ,剩下的数组为 nums = [6,7,4,1] 。
选择删除下标 2 ,剩下的数组为 nums = [6,1,4,1] 。
选择删除下标 4 ,剩下的数组为 nums = [6,1,7,4] 。
如果一个数组满足奇数下标元素的和与偶数下标元素的和相等,该数组就是一个平衡数组 。
请你返回删除操作后,剩下的数组 nums 是平衡数组的方案数 。
来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/ways-to-make-a-fair-array/
二、C解法
我的思路及代码
使用ans存储当前平衡方案数,两个变量存储奇数项和偶数项和,从删除nums[0]开始,计算奇偶数项和。可以认为这里的奇数项和与偶数项和为初始状态,然后删除nums[1],对于偶数项来说,要减掉之前nums[1]的元素,然后加上nums[0]的元素(因为在之前删除nums[0]的时候,nums[1]发生变化取代了nums[0]的位置,所以会被偶数项和计算进去。现在删除nums[1],那么nums[0]则不会被影响,所以要按照原逻辑处理),后面过程以此类推进行状态转移,每次转移后对奇数项和与偶数项进行判断是否相等,若相等则ans++,最后返回ans。
- 时间复杂度:O(n),其中 n 为数组 nums 的长度
- 空间复杂度:O(1),仅使用常量空间
int waysToMakeFair(int* nums, int numsSize){
int ans=0;
int sumOdd=0,sumEven=0;
//删除下标0后的奇数项和与偶数项和
for(int i=0;i<numsSize;i++){
if(i%2!=0){
sumEven+=nums[i];
}else{
sumOdd+=nums[i];
}
}
sumOdd-=nums[0];
if(sumEven==sumOdd){
ans++;
}
//进行状态转移
for(int i=1;i<numsSize;i++){
if(i%2==1){
sumEven =sumEven- nums[i]+nums[i-1];
}else {
sumOdd =sumOdd- nums[i]+nums[i-1];
}
if(sumEven==sumOdd){
ans++;
}
}
return ans;
}
官方参考代码
随便看看就行,没有我的简洁
官方思路:
- 时间复杂度:O(n),其中 n 为数组 nums 的长度
- 空间复杂度:O(1),仅使用常量空间
int waysToMakeFair(int* nums, int numsSize) {
int odd1 = 0, even1 = 0;
int odd2 = 0, even2 = 0;
for (int i = 0; i < numsSize; ++i) {
if (i & 1) {
odd2 += nums[i];
} else {
even2 += nums[i];
}
}
int res = 0;
for (int i = 0; i < numsSize; ++i) {
if (i & 1) {
odd2 -= nums[i];
} else {
even2 -= nums[i];
}
if (odd1 + even2 == odd2 + even1) {
++res;
}
if (i & 1) {
odd1 += nums[i];
} else {
even1 += nums[i];
}
}
return res;
}