问题本质 :判断一个整数数组 arr 能否被分割成三个和相等的非空连续子数组 。
核心思路:
- 必要条件 :数组总和
sum必须能被 3 整除,即sum % 3 == 0。否则直接返回false。 - 目标部分和 :每个部分的目标和
target = sum / 3。 - 寻找分割点 :遍历数组,累加当前和
curSum。当curSum第一次等于target时,找到第一个分割点i;继续遍历,当curSum第二次等于2 * target时,找到第二个分割点j,且此时j不能是数组最后一个元素(保证第三部分非空)。 - 判断结果:如果成功找到两个分割点,则数组可被分成三个和相等的部分。
C++ 代码实现:
cpp
class Solution {
public:
bool canThreePartsEqualSum(vector<int>& arr) {
int total = accumulate(arr.begin(), arr.end(), 0);
// 总和必须能被3整除
if (total % 3 != 0) {
return false;
}
int target = total / 3;
int n = arr.size();
int curSum = 0;
int count = 0; // 记录找到的和为 target 的段数 for (int i = 0; i < n; ++i) {
curSum += arr[i];
// 当累加和等于 target 时,找到一段
if (curSum == target) {
count++;
curSum = 0; // 重置当前和,开始下一段的累加
}
// 如果已经找到两段,且当前不是最后一段(即后面还有元素),则成功
if (count == 2 && i < n - 1) {
return true;
}
}
// 遍历结束仍未找到两段,或最后一段和不为 target,则失败 return false;
}
};
复杂度分析:
- 时间复杂度:O(n),其中 n 是数组长度。仅需一次遍历 。
- 空间复杂度:O(1),只使用了常数个额外变量 。