给出一组整数,例如,{19,27,42,...},现在想请您把他们分成三堆,使得每一堆的和相等:
a、如何判断该问题是否有解?
b、请给出解决方案的算法(尽可能每一小组相等的算法)。
c、您的算法时间复杂度(running time)多少?为什么?
------解决方案--------------------
一个扯蛋的解法,参考Bingo排序
把所有的数字往天上一抛,然后数字落在地上,按顺序分成3分,如果符合要求则成功,否则继续抛。
------解决方案--------------------
分成三队,一个数可以算一堆?比如[100,50,50,25,25,30,20],
分成三堆100;50,50; 25,25,30,20;
还带有好几种,,,
------解决方案--------------------
import java.util.Arrays;
public class IntGroup {
public int[][] data;
public int groups;
public IntGroup(int[] ints, int groups) {
this.groups = groups;
int[] clone = ints.clone();
Arrays.sort(clone);
data = new int[clone.length][2];
for (int i=0; i<clone.length; i++) {
data[i][0] = clone[ints.length-1-i];
data[i][1] = 0;
}
}
private boolean group(int sum, int flag) {
if (flag==0)
return true;
int sum_tmp=0;
int[] ids = new int[data.length];
int c=0;
int id=0;
while (true) {
if (sum_tmp==sum) {
if (group(sum, flag-1))
return true;
else {
if (c==0)
return false;
data[ids[c-1]][1] = 0;
id = ids[c-1]+1;
c--;
}
}
if (data[id][1]>0) {
id++;
continue;
}
if (id >= data.length) {
if (c==0)
return false;
data[ids[c-1]][1] = 0;
id = ids[c-1]+1;
c--;
}
int x = sum_tmp+data[id][0];
if (x <= sum) {
data[id][1] = flag;
ids[c] = id;
c++;
id++;
sum_tmp = x;
} else
id++;
}
}
public void print() {
for (int i=0; i<groups; i++)
{
for (int j=0; j<data.length; j++) {
if (data[j][1] == i)
System.out.print(data[j][0] + " ");
}
System.out.println();
}
}
public boolean group() {
if (groups<=0)
return false;
int allsum=0;
for (int i=0; i<data.length; i++)
allsum += data[i][0];
if (allsum % groups != 0)
return false;
int sum = allsum/groups;
if (data[0][0] > sum)
return false;
return group(sum, groups-1);
}
public static void main(String[] args) {
int[] array = {1,2,3,4,5,6,7,8};
IntGroup ig = new IntGroup(array, 3);
if (ig.group()) {
System.out.println("Group succeeds!");
ig.print();
}
else
System.out.println("Group fails!");
}
}
上面的代码不但可以分3堆,而且可以分任意多堆,供楼主参考。
这个算法的时间复杂度属于比较原始的,还有一些可优化的地方,又不是面试就没进一步考虑了。抛砖引玉,欢迎大家讨论。