Dynamic Programming学习笔记 (48) - 生成平衡数组的方案数 (力扣# 1664)

118 阅读2分钟

本题出自力扣题库第1664题。题面大意如下:

给定一个整数数组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成为平衡数组

示例:

输入:nums = [2,1,6,4]
输出:1
解释:删除下标 1 :[2,6,4] -> 偶数元素下标为:2 + 4 = 6 。奇数元素下标为:6 。平衡。
只有一种让剩余数组成为平衡数组的方案。

题解:

以长度为5的数组为例,可能的删除方案有以下几种:

1)删除下标0,判读是否相等: [1]+[3] = [2]+[4]
2)删除下标1,判读是否相等: [0]+[3] = [2]+[4]
3)删除下标2,判读是否相等: [0]+[3] = [1]+[4]
4)删除下标3,判读是否相等: [0]+[2] = [1]+[4]
5)删除下标4,判读是否相等: [0]+[2] = [1]+[3]

从中我们可以发现当删除下标i是大于0的偶数时,左边之和与前一个下标一样,右边之和是前一个下标之和减去nums[i]在加上nums[i - 1];当i是奇数时,左边之和是前一个下标之和减去nums[i]在加上nums[i - 1], 右边之和与前一个下标一样。由此,我们可以实现一个单层的循环来依次计算各个数组下标对应的左右两边之和并判断是否两种是否相等。

Java代码如下:

class Solution {
    public int waysToMakeFair(int[] nums) {
        int sumL = 0, sumR = 0;

        for (int i = 1; i < nums.length; i ++) {
            if (i % 2 == 0) {
                sumR += nums[i];
            } else {
                sumL += nums[i];
            }
        }

        int count = 0;
        if (sumL == sumR) {
            count ++;
        }

        for (int i = 1; i < nums.length; i ++) {
            if (i % 2 == 0) {
                sumR = sumR - nums[i] + nums[i - 1];
            } else {
                sumL = sumL - nums[i] + nums[i - 1];
            }
            if (sumL == sumR) {
                count ++;
            }
        }

        return count;
    }
}