leetcode 1013 将数组分成和相等的三个部分

题目描述

给你一个整数数组 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] ]

就可以将数组三等分。

建模

设数组 A 含有 n 个元素。

首先,分别求出 j 和 i 的定义域:

由题意知,

[i + 1 leq j - 1 ]

[j leq n - 1 ]

则 j 的定义域为

[i + 2 leq j leq n - 1 ]

由题意知,

[0 leq i ]

[i + 1 < j ]

则 i 的定义域为

[0 leq i < n - 2 ]

其次,分析题目知,为要使得 A 能够被分成数值相等的三部分,则 (sum_{k=0}^{n-1} A_k) 能够被 3 整除,否则就不能够被分成三个数组相等的部分。

最后,寻找 i 和 j,使得 (sum_{k=0}^{i} A_k)(sum_{k=i+1}^{j-1} A_k)(sum_{k=j}^{n-1} A_k) 都等于 (frac{1}{3} sum_{k=0}^{n-1} A_k)

如果不存在这样的 i 和 j,则返回 false。

代码

int sum(int* A, int beg, int end) {
 int total = 0, k = beg;
 while (k <= end) total += A[k++];
 return total;
}

bool canThreePartsEqualSum(int* A, int ASize) {
 int total = sum(A, 0, ASize - 1);
 if (total % 3) return false;
 int key = total / 3, i, j;
 for(i=0; i < ASize - 2; i++)
  if (sum(A, 0, i) == key) 
   break;
 if (sum(A, 0, i) != key) return false;
 for (j = i + 2; j < ASize; j++)
  if (sum(A, i + 1, j - 1) == key)
   break;
 if (j == ASize) return false;
 if (sum(A, i + 1, j - 1) != key) return false;
 if (sum(A, j, ASize - 1) != key) return false;
 return true;
}

执行结果:通过
执行用时 :1140 ms, 在所有 C 提交中击败了 5.37% 的用户
内存消耗 :8.3 MB, 在所有 C 提交中击败了100.00% 的用户

原文地址:https://www.cnblogs.com/fengyubo/p/12467827.html