1013. 将数组分成和相等的三个部分
1013. 将数组分成和相等的三个部分
题目
Given an array of integers arr, return true if we can partition the array into three non-empty parts with equal sums.
Formally, we can partition the array if we can find indexes i + 1 < j with (arr[0] + arr[1] + ... + arr[i] == arr[i + 1] + arr[i + 2] + ... + arr[j - 1] == arr[j] + arr[j + 1] + ... + arr[arr.length - 1])
Example 1:
Input: arr = [0,2,1,-6,6,-7,9,1,2,0,1]
Output: true
Explanation: 0 + 2 + 1 = -6 + 6 - 7 + 9 + 1 = 2 + 0 + 1
Example 2:
Input: arr = [0,2,1,-6,6,7,9,-1,2,0,1]
Output: false
Example 3:
Input: arr = [3,3,6,5,-2,2,5,1,-9,4]
Output: true
Explanation: 3 + 3 = 6 = 5 - 2 + 2 + 5 + 1 - 9 + 4
Constraints:
3 <= arr.length <= 5 * 10^4-10^4 <= arr[i] <= 10^4
题目大意
给你一个整数数组 arr,只有可以将其划分为三个和相等的 非空 部分时才返回 true,否则返回 false。
形式上,如果可以找出索引 i + 1 < j 且满足 (arr[0] + arr[1] + ... + arr[i] == arr[i + 1] + arr[i + 2] + ... + arr[j - 1] == arr[j] + arr[j + 1] + ... + arr[arr.length - 1]) 就可以将数组三等分。
示例 1:
输入: arr = [0,2,1,-6,6,-7,9,1,2,0,1]
输出: true
解释: 0 + 2 + 1 = -6 + 6 - 7 + 9 + 1 = 2 + 0 + 1
示例 2:
输入: arr = [0,2,1,-6,6,7,9,-1,2,0,1]
输出: false
示例 3:
输入: arr = [3,3,6,5,-2,2,5,1,-9,4]
输出: true
解释: 3 + 3 = 6 = 5 - 2 + 2 + 5 + 1 - 9 + 4
提示:
3 <= arr.length <= 5 * 10^4-10^4 <= arr[i] <= 10^4
解题思路
计算数组的总和
totalSum,如果totalSum不能被3整除,直接返回false,因为三个部分的和无法相等。每个部分的目标和为
target = totalSum / 3,我们需要找到三个这样的部分,使它们的和等于target。寻找分割点:
- 从左到右遍历数组,累加元素的值到
partSum。 - 每当累加和等于目标和
target时,说明可以分割出一个部分。 - 重置累加和
partSum = 0,继续寻找下一个部分。 - 当找到三个部分时,如果还有元素没有遍历完,继续累加剩余的元素和到
partSum。
- 从左到右遍历数组,累加元素的值到
如果遍历结束后,找到了三个部分,且剩余元素和
partSum == 0,返回true;否则,返回false。
复杂度分析
- 时间复杂度:
O(n),遍历数组两次,一次计算总和,一次寻找分割点。 - 空间复杂度:
O(1),仅使用常量级额外空间。
代码
/**
* @param {number[]} arr
* @return {boolean}
*/
return count == 3 && sum == 0
};
var canThreePartsEqualSum = function (arr) {
const totalSum = arr.reduce((acc, cur) => acc + cur, 0);
// 如果总和不能被 3 整除,直接返回 false
if (totalSum % 3 !== 0) return false;
const target = totalSum / 3;
let partSum = 0,
count = 0;
for (let num of arr) {
partSum += num;
if (partSum === target && count < 3) {
count++;
partSum = 0;
}
}
// 如果正好被分为 3 部分,返回 true
return count == 3 && partSum == 0;
};
相关题目
| 题号 | 标题 | 题解 | 标签 | 难度 | 力扣 |
|---|---|---|---|---|---|
| 1991 | 找到数组的中间位置 | [✓] | 数组 前缀和 | 🟢 | 🀄️ 🔗 |
