leetcode数组按序三等分

LeetCode每日一题

给你一个整数数组 A,只有可以将其划分为三个和相等的非空部分时才返回 true,否则返回 false。

形式上,如果可以找出索引 i+1 < j 且满足 (A[0] + A[1] + … + A[i] == A[i+1] + A[i+2] + … + A[j-1] == A[j] + A[j-1] + … + A[A.length - 1]) 就可以将数组三等分。

示例 1:

输出:[0,2,1,-6,6,-7,9,1,2,0,1]
输出:true
解释:0 + 2 + 1 = -6 + 6 - 7 + 9 + 1 = 2 + 0 + 1
示例 2:

输入:[0,2,1,-6,6,7,9,-1,2,0,1]
输出:false
示例 3:

输入:[3,3,6,5,-2,2,5,1,-9,4]
输出:true
解释:3 + 3 = 6 = 5 - 2 + 2 + 5 + 1 - 9 + 4

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/partition-array-into-three-parts-with-equal-sum
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

bool task(vector<int>& A) {
	int size = A.size(); int sum = 0;
	for (size_t i = 0; i < size; i++) sum += A[i]; 
	int i = 1;
	if (sum % 3 ) return 0; //快速判别给定数组是否合法
	else {
		sum /= 3; //数组三等分,则每一组之和均为原来的三分之一
		int t = A[0];  int count = 0;/组数
		while (count < 2 && i < size) {
/*先取前两组,再验证剩余数相加是否为0,若是简单循环count相加会有[10,-10,10,-10,10,
-10,10,-10]这个很尴尬的情况。*/
			while (t != sum && i < size)
			{
				t = t + A[i]; i++;
			}
			if (t == sum)
			{
				count++;
				if (i < size - 1)//防止数组越界
				{
					t = A[i];
					i++;
				}
				else if (i == size - 1) {
					t = A[i];
					if (t==sum)
					{
						count++; 
						if (count == 3) return 1;//若i已经在最后了就直接检验
						else return 0;
					}
				}
			}
		}
		if (i < size)//防止[1,-1,1,-1]这种正好两组的情况
		{
			while (i < size)//从第二组的下一个一直加到最后一个看是否为0
			{
				t += A[i];
				i++;
			}
			if (t == sum)
			{
				count++;
			}
			if (count == 3) return 1;
			else return 0;
		}
		else return 0;//两组直接pass
	}
}

leetcode 给出的解答。

   int s = accumulate(A.begin(), A.end(), 0);
        if (s % 3 != 0) {
            return false;
        }
        int target = s / 3;
        int n = A.size(), i = 0, cur = 0;
        while (i < n) {
            cur += A[i];
            if (cur == target) {
                break;
            }
            ++i;
        }
        if (cur != target) {
            return false;
        }
        int j = i + 1;
        while (j + 1 < n) {  // 需要满足最后一个数组非空
            cur += A[j];
            if (cur == target * 2) {
                return true;
            }
            ++j;
        }
        return false;
    }
/*
作者:LeetCode-Solution
链接:https://leetcode-cn.com/problems/partition-array-into-three-parts-with-equal-sum/solution/1013-jiang-shu-zu-fen-cheng-he-xiang-deng-de-san-2/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。*/

其中用到了accumulate函数,该算法在numeric头文件中定义。对stl容器适合使用。
accumulate(A.begin(), A.end(), 0) 会返回从A的开头加到A的结尾再加0的值。
更为简洁的是,它只要求找到第一个划分点i,然后往后找第二个划分点j,如果在最后一个数之前找到了第二个划分点,就绝对ok,剩下的不空的数组之和必定是sum/3。
而更暴力的一种写法如下:

bool task_3(vector<int>& A) {
	int sum = accumulate(A.begin(), A.end(), 0);
	if (sum % 3 != 0) {
		return false;
	}
	int count = 0, subSum = 0;
	for (int i = 0; i < A.size(); i++) {
		subSum += A[i];
		if (subSum == sum / 3) {
			count++;
			subSum = 0;
		}
		if (count == 3) {
			return true;
		}
	}
	return false;
}
/*作者:huwt
链接:https ://leetcode-cn.com/problems/partition-array-into-three-parts-with-equal-sum/solution/jiang-shu-zu-fen-cheng-he-xiang-deng-de-san-ge-b-6/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。*/

虽然对于数组[1,-1,1,-1,1,-1,1,-1]的count是4,但是在3的时候就直接返回了!
结合上述思路,我给出的解的

if (i < size)//防止[1,-1,1,-1]这种正好两组的情况
		{
			while (i < size)//从第二组的下一个一直加到最后一个看是否为0
			{
				t += A[i];
				i++;
			}
			if (t == sum)
			{
				count++;
			}
			if (count == 3) return 1;
			else return 0;
		}

为废话,剩下的肯定等于三分之一啊,要不不闹鬼了。于是直接

if (i < size)
		{
			return 1;
		}
		else return 0;

即可。

多思考发现规律,别硬写!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值