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% 的用户
智慧在街市上呼喊,在宽阔处发声。