问题描述
n 个整数两两相加可以得到 n(n - 1) / 2 个和。我们的目标是:根据这些和找出原来的 n 个整数。
按非降序排序返回这 n 个数,如果无解,输出 "Impossible"。
算法选择
数学 + 模拟
算法思路
-
排序和检查:首先,将给定的和数组
sums按照非降序排序。然后检查是否有可能找到满足条件的整数。对于n个整数,两两相加可以得到n(n-1)/2个和。如果sums的长度不等于n(n-1)/2,则直接返回 "Impossible"。 -
计算第一个整数:假设
sums中最小的和是sums[0],第二小的和是sums[1],最大的和是sums[n(n-1)/2 - 1]。设这n个整数中最小的两个数为a和b(a <= b),最大的数为c。那么sums[0] = a + b,sums[1] = a + c,sums[n(n-1)/2 - 1] = b + c。通过这三个方程,我们可以解出a:a=sums[0]+sums[1]−sums[n(n−1)/2−1]2a=2sums[0]+sums[1]−sums[n(n−1)/2−1]
如果
a不是整数,那么返回 "Impossible"。 -
计算其他整数:一旦我们有了
a,我们就可以计算出其他整数。因为sums[0] = a + b,所以b = sums[0] - a。接下来,我们可以使用sums中的其他和来找到其他整数。例如,sums[2] = a + d,所以d = sums[2] - a,以此类推。
代码展示
public class Main {
public static String solution(int n, int[] sums) {
StringBuilder sb = new StringBuilder();
if (n == 1) {
return sb.append(sums[0]).toString();
}
if (n == 2) {
return "Impossible";
}
// Please write your code here
Arrays.sort(sums);
if ((sums[0] + sums[1] - sums[n - 1]) % 2 == 1) {
return "Impossible";
}
int ans = (sums[0] + sums[1] - sums[n - 1]) / 2;
List<Integer> list = new ArrayList<>();
list.add(ans);
int l = 1;
for (int i = 0; i < n - 1; i++) {
if(l+1<list.size()){
if(list.get(l) + list.get(l+1) == sums[i]){
l+=2;
}
}else{
list.add(sums[i]-ans);
}
}
return sb.toString();
}
public static void main(String[] args) {
// You can add more test cases here
int[] sums1 = { 1269, 1160, 1663 };
int[] sums2 = { 1, 1, 1 };
int[] sums3 = { 226, 223, 225, 224, 227, 229, 228, 226, 225, 227 };
int[] sums4 = { -1, 0, -1, -2, 1, 0, -1, 1, 0, -1 };
int[] sums5 = { 79950, 79936, 79942, 79962, 79954, 79972, 79960, 79968, 79924, 79932 };
System.out.println(solution(3, sums1).equals("383 777 886"));
System.out.println(solution(3, sums2).equals("Impossible"));
System.out.println(solution(5, sums3).equals("111 112 113 114 115"));
System.out.println(solution(5, sums4).equals("-1 -1 0 0 1"));
System.out.println(solution(5, sums5).equals("39953 39971 39979 39983 39989"));
}
}