题目描述
给你一个整数数组 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]) 就可以将数组三等分。
示例 1:
输出:[0,2,1,-6,6,-7,9,1,2,0,1]
输出:true
解释:0 + 2 + 1 = -6 + 6 - 7 + 9 + 1 = 2 + 0 + 1
示例 2:
输入:[0,2,1,-6,6,7,9,-1,2,0,1]
输出:false
示例 3:
输入:[3,3,6,5,-2,2,5,1,-9,4]
输出:true
解释:3 + 3 = 6 = 5 - 2 + 2 + 5 + 1 - 9 + 4
思路一:纯暴力
从左到右,一部分一部分确定,两层循环
我超出时间限制了
代码
class Solution {
public boolean canThreePartsEqualSum(int[] A) {
int sum_1 = 0;
int sum_2 = 0;
int sum_3 = 0;
for(int i=0;i<A.length-2;++i)
{
sum_1 += A[i];
sum_2 = 0;
for(int j=i+1;j<A.length-1;++j)
{
sum_2 += A[j];
int k = j+1;
sum_3 = 0;
while(k<A.length)
{
sum_3 += A[k++];
}
if(sum_3==sum_2&&sum_1==sum_2)
{
return true;
}
}
}
return false;
}
}
思路二 双指针:
1、三部分和相等,那么第一个索引点先找和为三分之总和的位置(不止一个
2、一般三部分都是从两头找起比较快
3、左右两个指针还未相遇,且两侧都达到三分之一总和,return true
!!!看题解还可以加上:总和不是三的倍数可以直接淘汰
代码
class Solution {
public boolean canThreePartsEqualSum(int[] A) {
int sum = 0;
for(int i=0;i<A.length;++i)
{
sum += A[i];
}
if(sum%3!=0)
return false;
int sum_1 = A[0];
int sum_2 = A[A.length-1];
int m = 0;
int n = A.length-1;//俩指针
while(m+1<n)//毕竟是三部分
{
if(sum_1*3 == sum && sum_2*3 == sum)
return true;
if(sum_1*3!=sum)//千万不要写成< 正负都有
{
++m;
sum_1 += A[m];
}
if(sum_2*3!=sum)
{
--n;
sum_2 += A[n];
}//这地方不用管两边是不是同时移动,没达到sum/3就得动
}
return false;
}
}
思路三 半暴力:
1、三部分和相等,那么第一个索引点先找和为三分之总和的位置(不止一个
2、依旧是双循环,不过先找到第一个节点,再去进行后面的判断。
代码
class Solution {
public boolean canThreePartsEqualSum(int[] A) {
int sum = 0;
for(int i=0;i<A.length;++i)
{
sum += A[i];
}
int sum_1 = 0;
int sum_2 = 0;
for(int i=0;i<A.length-2;++i)
{
sum_1 += A[i];
if(sum_1*3==sum)
{
for(int j=i+1;j<A.length-1;++j)
{
sum_2 += A[j];
if(sum_2==sum_1)
{
return true;
}
}
}
}
return false;
}
}