本人大三,最近想找实习,看到阿里正在招聘实习生,便开始准备面试阿里的2018暑期Java实习,在看到2017的暑期Java实习在线编程题时,费了九牛二虎之力才把题目完成,贼蓝瘦。以下解法本人感觉没问题,望各位大神指点迷津,感激不尽!
题目:一个整型(非负)数组,将其划分为总和相同的4个切片,例如:{2,5,1,1,1,1,4,1,7,3,7},切片操作后划分为:{2,5},{1,1,1,4},{7},{7},也就找到所谓的四等分点,切分点分别是1,1,3,切分点不算在总和内。输出能否分片。要求时间复杂度和空间复杂度为o(n)。
思路:1、将数组先二等分,记为l,r,其中 l 为数值第一个元素下标,r 为数组最后一个元素下标。
2、增大 l 或减小 r ,使得左右两段和相等,记为lsum,如果无法相等,则不可分,否则进行第三步。
3、对剩下中间的数组同理进行分段,令ml = l+2;mr = r-2。进行类似第二步的操作,得到当左右两段相等的和,记为mlsum。
4、若lsum == mlsum,则可分,否则不可分。
以下是代码:
package com.alibaba.interview;
public class FourPoint {
public static boolean isFourPoint(int[] a) {
// 将数组分为两段
int l = 0, r = a.length - 1;
int lsum = a[0], rsum = a[a.length - 1];
// 先让左右两段和相等
while (true) {
//若左右无法相等,则不可分
if (l == r) {
return false;
}
if (lsum > rsum) {
--r;
rsum = rsum + a[r];
} else if (lsum < rsum) {
l++;
lsum = lsum + a[l];
} else {
break;
}
}
// 同理分段
int ml = l + 2;
int mr = r - 2;
int mlsum = a[ml];
int mrsum = a[mr];
while (true) {
//若中间的左右无法相等,则不可分
if (ml == mr) {
return false;
}
if (mlsum > mrsum) {
--mr;
mrsum = mrsum + a[mr];
} else if (mlsum < mrsum) {
ml++;
mlsum = mlsum + a[ml];
} else {
break;
}
}
if (mlsum == lsum) {
l++;
ml++;
r--;
System.out.println("分割点:" + a[l] + "," + a[ml] + "," + a[r]);
return true;
}
return false;
}
public static void main(String[] args) {
int[] a = { 2, 5,1, 1, 4, 1, 7, 3, 7 };
if (FourPoint.isFourPoint(a)) {
System.out.println("可以分片");
} else {
System.out.println("不可以分片");
}
}
}