【Leetcode】1013. Partition Array Into Three Parts With Equal Sum(配数学证明)

题目地址:

https://leetcode.com/problems/partition-array-into-three-parts-with-equal-sum/

给定一个数组 A A A,问是否能将 A A A拆成 3 3 3段,使得每段非空,并且每段数字和相等。

先求一下 A A A的数字和 s s s,则每段的数字和应当为 s / 3 s/3 s/3。如果 s s s不能被 3 3 3整除那直接返回false。接下来开始截取 A A A中和为 s / 3 s/3 s/3的一段,并对段数进行计数,设最终计数为 c c c。如果 c = 3 c=3 c=3或者 s = 0 s=0 s=0并且 c ≥ 3 c\ge 3 c3,就说明可以拆成和相等的 3 3 3段,返回true,否则返回false。

算法正确性证明:
首先算法返回true,则 A A A一定能拆成和相等的 3 3 3段,这一点很显然。如果算法返回false,但 A A A仍然可以拆成和相等的 3 3 3段,如果 s = 0 s=0 s=0,那么算法得到的 c ≥ 3 c\ge 3 c3,应该返回了true,矛盾;如果 s ≠ 0 s\ne 0 s=0,首先算法算出的 c c c一定满足 c ≥ 3 c\ge 3 c3,如果 c > 3 c>3 c>3,那么说明存在超过 3 3 3段的子段和等于 s / 3 s/3 s/3,则 A A A总和应该等于 c s / 3 ≠ s cs/3\ne s cs/3=s矛盾,所以 c = 3 c=3 c=3,应该返回true,矛盾。所以算法正确。

代码如下:

public class Solution {
    public boolean canThreePartsEqualSum(int[] A) {
        int sum = 0;
        for (int i = 0; i < A.length; i++) {
            sum += A[i];
        }
        
        if (sum % 3 != 0) {
            return false;
        }
    
        int curSum = 0, count = 0;
        for (int i = 0; i < A.length; i++) {
            curSum += A[i];
            if (curSum == sum / 3) {
                count++;
                curSum = 0;
            }
        }
        
        return count == 3 || (sum == 0 && count >= 3);
    }
}

时间复杂度 O ( n ) O(n) O(n),空间 O ( 1 ) O(1) O(1)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值