题目描述
模拟
逆向思维(删除元素的性质):删除数组的某个元素,左侧元素的下标不变,右侧元素的下标发生奇偶替换。
- 算法流程
① 由于算法从右往左枚举,预处理左侧的奇数下标元素之和oddl
,偶数下标元素之和evenl
。 - 考虑从右往左,枚举数组元素。
② 删除元素,等价于左侧减去这个元素。
③ 由删除元素的性质,可知,删除数组的某个元素后,左侧元素的下标不变,右侧下标发生奇偶替换。考虑整个数组,奇数下标元素之和是oddl + evenr
,偶数下标元素之和是evenl + oddr
。
④ 为了维持数组之和不变,维护右侧被删除的元素之和oddr
、evenr
。
class Solution {
public:
int waysToMakeFair(vector<int>& nums) {
int oddl = 0, evenl = 0, oddr = 0, evenr = 0, n = nums.size();
for (int i = 0; i < n; i ++)
if (i & 1) oddl += nums[i];
else evenl += nums[i];
int ans = 0;
for (int i = n - 1; i >= 0; i --) {
if (i & 1) oddl -= nums[i];
else evenl -= nums[i];
if (oddl + evenr == evenl + oddr) ans ++;
if (i & 1) oddr += nums[i];
else evenr += nums[i];
}
return ans;
}
};
class Solution:
def waysToMakeFair(self, nums: List[int]) -> int:
oddl, evenl, oddr, evenr, ans = 0, 0, 0, 0, 0
for i, x in enumerate(nums):
if i & 1: oddl += x
else : evenl += x
for i in range(len(nums) - 1, -1, -1):
if i & 1: oddl -= nums[i]
else : evenl -= nums[i]
if oddl + evenr == evenl + oddr: ans += 1
if i & 1: oddr += nums[i]
else : evenr += nums[i]
return ans
- 时间复杂度 : O ( n ) O(n) O(n) , n n n 是数组长度 ,预处理数组,一次遍历的时间复杂度 O ( n ) O(n) O(n) 。
- 空间复杂度 : O ( 1 ) O(1) O(1) , 只使用常量级空间 。
AC
致语
- 理解思路很重要
- 读者有问题请留言,清墨看到就会回复的。