[LeetCode每日1题][简单] 1013. 将数组分成和相等的三个部分

题目

1013. 将数组分成和相等的三个部分 - 力扣(LeetCode)
在这里插入图片描述

前缀和解法

思路
  1. 遍历数组,并维护一个前缀和数组preSum,方便后面求区间和
  2. 数组和sum = preSum[size]-1
  3. 如果sum%3 != 0 返回false
  4. 遍历preSum,寻找preSum[i] == sum/3,如果i不存在,返回false
  5. 从后往前遍历preSum求后缀和,寻找preSum[size-1]-preSum[j] == sum/3,如果j存在,返回true
复杂度分析

遍历一次原数组和前缀和数组,时间复杂度O(n)
多使用了一个前缀和数组,空间复杂度O(n)

实现
class Solution {
public:
    bool canThreePartsEqualSum(vector<int>& A) {
        int size = A.size();
        if(size<3) return false;
        vector<int> preSum;
        preSum.push_back(A[0]);
        for(int i=1;i<size;i++) {
            preSum.push_back(preSum[i-1]+A[i]);
        }

        int lastIndex = size-1;
        int sum = preSum[lastIndex]/3;

        if(preSum[lastIndex]%3 != 0) return false;
        
        int ii = -1;
        for(int i=0;i<size;i++) {
            if(preSum[i] == sum) {
                ii = i;
                break;
            }
        }
        if(ii == -1) return false;
        
        int jj = -1;
        for(int i=lastIndex-1;i>ii;i--) {
            if(preSum[lastIndex]-preSum[i] == sum) {
                jj = i;
                break;
            }
        }
        return jj!=-1;
    }
};
优化

可以不用前缀和数组,优化空间复杂度到O(1):
先求出数组的和sum,然后再次遍历求和curSum,遇到sum/3,则k++curSum = 0,最后返回k==3
由于还是遍历了两次,时间复杂度和前缀和解法一致。

class Solution {
public:
    bool canThreePartsEqualSum(vector<int>& A) {
        int sum = 0, currSum = 0, k = 0;
        for(auto it : A)
            sum += it;
        if(sum % 3 != 0)
            return false;
        for(auto it : A)
        {
            currSum += it;
            if(currSum == sum / 3){
                currSum = 0;
                k++;
            }
        }
        if(currSum == sum / 3)
            k++;
        return k==3;           
    }
};

C++复习

  • 二分查找 bool binary_search(arr.begin(), arr.end(), target)
  • 累计求和 int accumulate(arr.begin(), arr.end(), initVal)

参考

【将数组分成和相等的三个部分】:简洁的C++ - 将数组分成和相等的三个部分 - 力扣(LeetCode)

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值