今天做了个有意思的题目,分享下。
输入一个数组,判断能否抽取三个数,余下的数正好以抽取数的位置将原始数组四等分。
如下测试用例,抽取红色字,能分四等分。
int[] a = { 2, 5, 1, 1, 1, 1, 4, 1, 7, 3, 7 }; //返回true
int[] b={10,2,11,13,1,1,1,1,1};
int[] c={};
int[] d={1,1,1,5,3,9,1,2,7,2,1}; //返回true
int[] e={1,2,3,4,5,6,7};
int[] f={1,2,3};
代码:
package com.mytest.designpartter;
public class Mytest00001 {
/**
*
*/
public static void main(String[] args) {
int[] a = { 2, 5, 1, 1, 1, 1, 4, 1, 7, 3, 7 };
int[] b={10,2,11,13,1,1,1,1,1};
int[] c={};
int[] d={1,1,1,5,3,9,1,2,7,2,1};
int[] e={1,2,3,4,5,6,7};
int[] f={1,2,3};
System.out.println(fensi(a));
System.out.println(fensi(b));
System.out.println(fensi(c));
System.out.println(fensi(d));
System.out.println(fensi(e));
System.out.println(fensi(f));
}
private static boolean fensi(int[] a) {
if (a.length < 7 || a==null)
return false;
int i = 0, j = a.length - 1;
int i2=0,j2=0;
long p = a[i], q = a[j];
while (i<j-3){
if (p < q ) {
i++;
p = p + a[i];
}
if (p > q ) {
j--;
q = q + a[j];
}
i2=i;
j2=j;
if(p==q){//第一四份相等,检查第二份和第三份是否和一四份相等
i=i+2;j=j-2;
long p2=a[i];
long q2=a[j];
//检查2,3份是否合乎规范
while(i<j-2){
if(p2<q2){
i++;
p2=p2+a[i];
}
if(p2>q2 && i<j-2){
j--;
q2=q2+a[j];
}
if(p2==q2 && i<j-2){
i++;
p2=p2+a[i];
}
}
if(p2==q2 && p==p2 && i+2==j){//找到
return true;
}
if(p2+q2>p+q){//没找到
j=j2;
i=i2;
i++;
p=p+a[i];
}
}
}
return false;
}
}
总结:从前往后,从后往前找,先找第一份和第四份,然后找第二和第三份,如果第二三份不成立,需要回溯到第一四份相等的点继续找下个可能的点。