生成平衡数组的方案数[抽象前缀和思想]

前言

空间换时间,利用前缀和快速获得一段子数组的和,或者抽象一段子数组,比如不一定全加,可以加减交替。

一、生成平衡数组的方案数

在这里插入图片描述

二、抽象前缀和

1、想法

直接想法:尝试删除每个元素,看奇偶位置上的值是否相等。
在此基础上换个角度:顺序访问,先加后减,知道末尾,看为0否?
新角度:联系上前缀和思想,遍历数组,不断更新以当前元素为中点,左右两段子数组的抽象前缀和,两者相减是否为0,即是否平衡。

2、Java

class Solution {
    // 尝试删除每个元素,看奇偶位置上的值是否相等。
    // 换个角度:顺序访问,先加后减,知道末尾,看为0否?
    // 类前缀和,求得nums所有元素加减和,遍历数组,除去当前元素,是否平衡,再更新前段子数组和,后段子数组和。
    public int waysToMakeFair(int[] nums) {
        int sum = 0,step = 1;
        // 后段子数组和。
        for(int n : nums) {
            sum += step * n;
            step = -step;
        }

        int pre = 0;// 前段子数组和
        step = 1;
        int cnt = 0;
        for(int i = 0;i < nums.length;i++){
            sum -= step * nums[i];
            // pre + (-sum) 少了一个就得变向,变加减的方向。
            if(pre - sum == 0) cnt++;

            pre += step * nums[i];
            step = -step;
        }
        return cnt;
    }
}

3、go

func waysToMakeFair(nums []int) int {
    sum := getSum(nums)

    pre,step,cnt := 0,1,0
    for _,n := range nums {
        sum -= step * n

        if pre + (-sum) == 0 {
            cnt++
        }
        pre += step * n
        step = -step
    }
    return cnt
}
func getSum(nums []int) int {
    sum,step := 0,1
    for _,n := range nums {
        sum += step * n
        step = -step
    }
    return sum
}

总结

1)一个好的角度不是一下子来的,除法积累众多,否则需要从所谓的暴力慢慢分析过来。
2)抽象思维确实好用,像这里的抽象前缀和,同样空间换时间。

参考文献

[1] LeetCode 生成平衡数组的方案数

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值