Java 如何找到数组中最接近零的两个元素之和
如何从一个数组中找到两个元素,其和最接近于零但不是零(注意:-1最接近于零而不是+2)。我尝试了这个Java 如何找到数组中最接近零的两个元素之和,java,Java,如何从一个数组中找到两个元素,其和最接近于零但不是零(注意:-1最接近于零而不是+2)。我尝试了这个 int a[]=new int[n]; int b[]=new int[2]; int prev=0; for(int i=0;i<n;a[i++]=in.nextInt()); for(int i=0;i<a.length;i++){ for(int j=i+1;j<a.length;j++){ int sum=a[i]+a[j];
int a[]=new int[n];
int b[]=new int[2];
int prev=0;
for(int i=0;i<n;a[i++]=in.nextInt());
for(int i=0;i<a.length;i++){
for(int j=i+1;j<a.length;j++){
int sum=a[i]+a[j];
if(prev==0)
prev=sum;
if(sum > 0){
if(sum < prev ){
prev=sum;
b[0]=a[i];
b[1]=a[j];
}
}
else if(sum < 0){
if(-sum < prev){
prev=sum;
b[0]=a[i];
b[1]=a[j];
}
}
}
}
Sop(b[0]+" "+b[1]);
inta[]=newint[n];
int b[]=新int[2];
int prev=0;
对于(int i=0;i您可以尝试:
int a[]=new int[n];
int b[]=new int[2];
int prev=0;
for(int i=0;i<n;a[i++]=in.nextInt());
for(int i=0;i<a.length;i++){
for(int j=i+1;j<a.length;j++){
int sum=a[i]+a[j];
if(prev==0)
prev=sum;
if(Math.abs(sum)>0 && Math.abs(sum)<Math.abs(prev)){
prev=sum;
b[0]=a[i];
b[1]=a[j];
}
}
}
Sop(b[0]+" "+b[1]);
inta[]=newint[n];
int b[]=新int[2];
int prev=0;
对于(int i=0;i我有几点意见,您使用了3个for循环,这可以改进为2个嵌套for循环(外部循环用于选择当前元素,内部循环用于与其他元素进行比较)
此外,您还有多个if测试来检查总和现在是否比上一个总和更接近于零。但是,这些if测试可以减少为一个if测试,方法是取总和的绝对值,而不是在sum>0
和sum<0
上进行测试,这对可读性很好
这就是我想到的:
int array[] = new int[5];
array[0] = -3; array[1] = -2; array[2] = -1; array[3] = 1; array[4] = 2; // Fill array
int idx[] = new int[2]; // Will store the result (index of the two elements that need to be added)
double lowest_sum = Double.POSITIVE_INFINITY; // Of type double to be able to use infinity
for(int i = 0; i < array.length; i++) {
// Outer loop --> Uses a current (array[i]) from left to right
int current = array[i];
for(int j = i+1; j < array.length; j++) {
// Inner loop --> Check all elements we didn't used as current till now
int compare_with = array[j];
if((Math.abs(current + compare_with) < lowest_sum) && ((current + compare_with) != 0)) {
// We found two elements whose sum is closer to zero
lowest_sum = Math.abs(current + compare_with);
idx[0] = i; // Index of the first element to add
idx[1] = j; // Index of second element to add
}
}
}
int res_idx1 = idx[0];
int res_idx2 = idx[1];
System.out.println("The first element to add is : " + array[res_idx1] + "\nThe second element to add is : " + array[res_idx2]);
int数组[]=newint[5];
数组[0]=-3;数组[1]=-2;数组[2]=-1;数组[3]=1;数组[4]=2;//填充数组
int idx[]=new int[2];//将存储结果(需要添加的两个元素的索引)
double lower_sum=double.POSITIVE_INFINITY;//类型为double,可以使用INFINITY
for(int i=0;i从左到右使用电流(数组[i])
int电流=阵列[i];
对于(int j=i+1;j检查到目前为止未用作当前元素的所有元素
int compare_with=数组[j];
如果((数学绝对值(当前值+比较值)<最低值和)&((当前值+比较值)!=0)){
//我们发现两个元素的和接近于零
最低总和=Math.abs(当前+比较);
idx[0]=i;//要添加的第一个元素的索引
idx[1]=j;//要添加的第二个元素的索引
}
}
}
int res_idx1=idx[0];
int res_idx2=idx[1];
System.out.println(“要添加的第一个元素是:“+array[res_idx1]+”\n要添加的第二个元素是:“+array[res_idx2]);
输入:数组=[-3,-2,-1,1,2],输出:要添加的第一个元素是:-3,
要添加的第二个元素是:2
请注意,此代码将打印一个解决方案,而不是所有解决方案(如果存在多个解决方案)。编辑代码以使其返回所有解决方案应该相当简单。此问题可以在O(N*log(N))中解决。在这种情况下,最昂贵的操作将是对数组进行排序。如果您的域允许您使用非比较排序,例如,则可以将整个解决方案的时间复杂度降低为线性时间
其思想是,在排序数组中,您可以并行地按升序和降序迭代元素,从而在线性时间内找到具有最小/最大和的所有对。将这种方法应用于任务中的唯一缺点是,您需要找到和的最小绝对值,这意味着在正和中找到最小值d负和中的最大值。这将需要两个线性过程
下面是我的解决方案。它通过随机数据与bruteforce O(N^2)解决方案进行验证
// note: mutates argument!
static Solution solve(int a[]) {
Arrays.sort(a);
int i = 0;
int j = a.length - 1;
// -1 indicates uninitialized min value
int minI = -1;
int minJ = -1;
int min = 0;
// finding maximal sum among negative sums
while (i < j) {
int cur = a[i] + a[j];
if (cur != 0 && (minI == -1 || Math.abs(cur) < Math.abs(min))) {
min = cur;
minI = i;
minJ = j;
}
// if current sum is below zero, increase it
// by trying the next, larger element
if (cur < 0) {
i++;
} else { // sum is already non-negative, move to the next element
j --;
}
}
i = 0;
j = a.length - 1;
// finding minimal sum among positive sums
while (i < j) {
int cur = a[i] + a[j];
if (cur != 0 && (minI == -1 || Math.abs(cur) < Math.abs(min))) {
min = cur;
minI = i;
minJ = j;
}
if (cur > 0) {
j--;
} else {
i ++;
}
}
if (minI >=0) {
return new Solution(minI, minJ, min);
//System.out.printf("a[%d]=%d, a[%d]=%d, sum=%d", minI, minJ, a[minI], a[minJ], min);
} else {
return null;
//System.out.println("No solution");
}
}
//注意:变异参数!
静态解算(int a[]){
数组。排序(a);
int i=0;
int j=a.长度-1;
//-1表示未初始化的最小值
int minI=-1;
int minJ=-1;
int min=0;
//求负和中的最大和
而(i0){
j--;
}否则{
i++;
}
}
如果(最小值>=0){
返回新的解决方案(minI、minJ、min);
//System.out.printf(“a[%d]=%d,a[%d]=%d,sum=%d”,minI,minJ,a[minI],a[minJ],min);
}否则{
返回null;
//System.out.println(“无解决方案”);
}
}
我刚刚意识到排序会弄乱索引,因此minI
和minJ
不会与原始未排序数组中的索引相对应。解决方法很简单-原始数组应转换为成对数组(值,原始索引)排序之前。虽然我不会在我的示例代码段中实现此修复,因为它会进一步影响可读性。当存在多个解决方案时,您希望的行为是什么?只打印一个解决方案还是打印所有解决方案?以及您尝试不工作的内容如何?您得到了什么输出?您希望得到什么输出?我只想打印两个el来自一个数组的元素,其总和接近于零,与符号无关。在我的代码中,第一个循环用于读取数组中的n个元素,其余两个循环用于操作。使用Math.abs是的,我们可以减少多个if语句,感谢您的建议,最后一件事是如果有多个解决方案,然后打印元素首先出现的是正确的,正如您所做的。是的,除了b[1]=b[j],代码是正确的,但它应该是b[1]=a[j];