[LeetCode] 1013. Partition Array Into Three Parts With Equal Sum

Given an array A of integers, return true if and only 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 (A[0] + A[1] + ... + A[i] == A[i+1] + A[i+2] + ... + A[j-1] == A[j] + A[j-1] + ... + A[A.length - 1])

Example 1:

Input: A = [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: A = [0,2,1,-6,6,7,9,-1,2,0,1]
Output: false

Example 3:

Input: A = [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 <= A.length <= 50000
  • -10^4 <= A[i] <= 10^4

将数组分成和相等的三个部分。题意是给你一个整数数组A,只有可以将其划分为三个和相等的非空部分时才返回true,否则返回false。

思路是two pointer。首先判断corner case,如果整个数组中所有元素的加和sum不能被3整除,则一定是false。然后双指针从两边逼近,看左边的leftSum和右边的rightSum是否能都得到1/3的sum。注意双指针while循环的退出条件是(left + 1 < right),如果写成(left < right)会报错,比如如下的case。

Input
[1,-1,1,-1]
Output
true
Expected
false

时间O(n)

空间O(n) - 用了两个数组存放leftSum和rightSum

Java实现

 1 class Solution {
 2     public boolean canThreePartsEqualSum(int[] A) {
 3         int sum = 0;
 4         for (int i : A) {
 5             sum += i;
 6         }
 7         // corner case
 8         if (sum % 3 != 0) {
 9             // 总和不是3的倍数,直接返回false
10             return false;
11         }
12 
13         // 使用双指针,从数组两头开始一起找,节约时间
14         int left = 0;
15         int leftSum = A[left];
16         int right = A.length - 1;
17         int rightSum = A[right];
18 
19         // 使用left + 1 < right 的原因,防止只能将数组分成两个部分
20         // 例如:[1,-1,1,-1],使用left < right作为判断条件就会出错
21         while (left + 1 < right) {
22             if (leftSum == sum / 3 && rightSum == sum / 3) {
23                 // 左右两边都等于 sum/3 ,中间也一定等于
24                 return true;
25             }
26             if (leftSum != sum / 3) {
27                 // left = 0赋予了初值,应该先left++,在leftSum += A[left];
28                 leftSum += A[++left];
29             }
30             if (rightSum != sum / 3) {
31                 // right = A.length - 1 赋予了初值,应该先right--,在rightSum += A[right];
32                 rightSum += A[--right];
33             }
34         }
35         return false;
36     }
37 }

JavaScript实现

 1 /**
 2  * @param {number[]} A
 3  * @return {boolean}
 4  */
 5 var canThreePartsEqualSum = function (A) {
 6     let sum = 0;
 7     for (num of A) {
 8         sum += num;
 9     }
10 
11     // corner case
12     if (sum % 3 !== 0) {
13         return false;
14     }
15 
16     // normal case
17     let left = 0;
18     let leftSum = A[left];
19     let right = A.length - 1;
20     let rightSum = A[right];
21     while (left + 1 < right) {
22         if (leftSum === sum / 3 && rightSum === sum / 3) {
23             // 左右两边都等于 sum/3 ,中间也一定等于
24             return true;
25         }
26         if (leftSum !== sum / 3) {
27             // left = 0赋予了初值,应该先left++,在leftSum += A[left];
28             leftSum += A[++left];
29         }
30         if (rightSum !== sum / 3) {
31             // right = A.length - 1 赋予了初值,应该先right--,在rightSum += A[right];
32             rightSum += A[--right];
33         }
34     }
35     return false;
36 };

LeetCode 题目总结

原文地址:https://www.cnblogs.com/cnoodle/p/12461640.html