找出两个元素之和的最小绝对值

时间:2019-09-03 07:11:04

标签: java arrays algorithm

我正在解决下面提供的Codility问题

让A为由N个整数组成的非空数组。

对于两个索引(P,Q)的绝对绝对值是绝对值| A [P] + A [Q] |,对于0≤P≤Q

例如,以下数组A:

  
    

A [0] = 1 A 1 = 4 A [2] = -3具有索引对(0,0),(0,     1),(0、2),(1、1),(1、2),(2、2)。该对的绝对绝对值2     (0,0)是A [0] + A [0] = | 1 + 1 | =2。该对的绝对绝对值2     (0,1)是A [0] + A 1 = | 1 + 4 | = 5.该对的绝对绝对值2     (0,2)是A [0] + A [2] = | 1 +(−3)| =2。绝对值为2     对(1,1)是A 1 + A 1 = | 4 + 4 | =8。绝对值为2     对(1,2)是A 1 + A [2] = | 4 +(−3)| =1。两个的绝对吸收     对(2,2)是A [2] + A [2] = |(−3)+(−3)| = 6.`

  

编写函数:

class Solution { public int solution(int[] A); }

在给定一个由N个整数组成的非空数组A的情况下,对于该数组中的任何一对索引,都返回2的最小绝对吸收和。

例如,给定以下数组A:

  

A [0] = 1 A 1 = 4 A [2] = -3函数应返回1,因为   

给出数组A:

  

A [0] = -8 A 1 = 4 A [2] = 5 A [3] = -10 A [4] = 3函数   应该返回|(−8)+ 5 | = 3。

为以下假设写出有效的算法:

N是[1..100,000]范围内的整数;数组A的每个元素都是[−1,000,000,000..1,000,000,000]范围内的整数。

我写了下面提供的解决方案。

public static int solution(int[] A) {

        int N = A.length;
        Arrays.sort(A);

        if (A[0] >= 0) {
            return 2 * A[0];
        }

        int i = 0;
        int j = N - 1;

        int sum = Math.abs((A[i] + A[j]));

        // -10, -8, 3, 4, 5
        while (i <= j) {

            if (Math.abs(A[i + 1] + A[j]) < sum) {

                ++i;
                sum = Math.abs(A[i] + A[j]);

            } else if (Math.abs(A[i] + A[j - 1]) < sum) {

                --j;
                sum = Math.abs(A[i] + A[j]);
            } else {

                i++;
                j--;
            }
        }

        return sum;
    }

该解决方案陷入了在线评委的困境,并且似乎陷入了永远的循环。代码是否有可能进入无穷循环?

  

更新

用所有否定检查更新解决方案后,代码通过了在线判断,并提供了良好的性能。

        if(A[N-1] <=0){
            return 2* Math.abs(A[N-1]);
        }

enter image description here

3 个答案:

答案 0 :(得分:1)

对于输入数组,例如({-1, -2, -3}{-1, -2}{-1},您的算法会引发ArrayIndexOutOfBoundsException,因此,当数组只有负数且没有重复项时会出现

因为i或j仅更改+或-1,所以没有机会达到无限循环

答案 1 :(得分:0)

我得到了 100% 的以下代码(java)。 https://www.techiedelight.com/find-pair-array-minimum-absolute-sum/ 的略微修改版本 enter image description here

import java.util.*;

// you can write to stdout for debugging purposes, e.g.
// System.out.println("this is a debug message");

class Solution {
    public int solution(int[] A) {
         // sort the array if it is unsorted
         Arrays.sort(A);
          int low = 0;
        int high = A.length - 1;
   if (A[0] >= 0) {
            return 2 * A[0];
        }
          if (A[high] <= 0) {
            return -2 * A[high];
        }
        // maintain two indexes pointing to endpoints of the array
       
 
        // `min` stores the minimum absolute difference
        int min = Integer.MAX_VALUE;
        int i = 0, j = 0;
 
        // reduce the search space `A[low…high]` at each iteration of the loop
        int sum = 0;
        // loop if `low` is less than `high`
        while (low < high)
        {
            // update the minimum if the current absolute sum is less.   
            sum = A[high] + A[low];
            if (Math.abs(sum) < min)
            {
                min = Math.abs(sum);
                i = low;
                j = high;
            }
 
            // optimization: pair with zero-sum is found
            if (min == 0) {
                break;
            }
 
            // increment `low` index if the total is less than 0;
            // decrement `high` index if the total is more than 0
            if (sum < 0) {
                low++;
            }
            else {
                high--;
            }
        }
        return min;

    }
    
}

答案 2 :(得分:0)

答案来晚了,但我希望能帮助任何有同样问题的人

//============================================================================
// Author: Hamdy Abd El Fattah
// Code is like humor. When you have to explain it, it’s bad.
//============================================================================
#include <bits/stdc++.h>
#define FIO cin.tie(0), cin.sync_with_stdio(0)
#define ll long long
#define INF 0x3f3f3f3f
using namespace std;
int main() {
    FIO;
    ll n , m = INF , x;
    vector<ll> positive,negative;
    cin>>n;
    while(n--){
        cin>>x;
        if(x < 0)
            negative.push_back(x * -1);
        else if(x > 0)
            positive.push_back(x);
        else
            m = 0;
    }

    if(m == 0){
        cout<<"0\n";
    }else{

        sort(positive.begin(), positive.end());
        sort(negative.begin(), negative.end());
        int i= 0, j = 0;
        int positive_size = positive.size(), negative_size =negative.size();
        while(i < positive_size || j < negative_size){
            if(abs(positive[i] - negative[j]) < m){
                m=abs(positive[i] - negative[j]);
                m=min(min(m,positive[i]*2),negative[j] * 2);
            }
            if((i < positive_size && positive[i] <= negative[j]) || j == negative_size)
                i++;
            else if((j < negative_size && positive[i] > negative[j]) || i == positive_size)
                j++;
        }
        cout<<m<<endl;
    }


    return 0;
}