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% 的用户

posted @ 2020-03-12 11:08  健康平安快乐  阅读(420)  评论(0编辑  收藏  举报