Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 从和等于给定数字的数组中计数对?_Java_Algorithm - Fatal编程技术网

Java 从和等于给定数字的数组中计数对?

Java 从和等于给定数字的数组中计数对?,java,algorithm,Java,Algorithm,我刚刚进行了一次在线编码访谈,其中一个问题是对于给定的整数数组,找出其总和等于某个数字的对数(作为方法中的参数传递)。例如,一个数组如下所示: int[] a = {3, 2, 1, 45, 27, 6, 78, 9, 0}; int k = 9; // given number 因此,将有2对(3,6)和(9,0),它们的和等于9。值得一提的是,这些对是如何形成的并不重要。平均值(3,6)和(6,3)将被视为同一对。我提供了以下解决方案(Java),很想知道我是否遗漏了任何边缘案例 publ

我刚刚进行了一次在线编码访谈,其中一个问题是对于给定的整数数组,找出其总和等于某个数字的对数(作为方法中的参数传递)。例如,一个数组如下所示:

int[] a = {3, 2, 1, 45, 27, 6, 78, 9, 0};
int k = 9; // given number
因此,将有2对(3,6)和(9,0),它们的和等于9。值得一提的是,这些对是如何形成的并不重要。平均值(3,6)和(6,3)将被视为同一对。我提供了以下解决方案(Java),很想知道我是否遗漏了任何边缘案例

public static int numberOfPairs(int[] a, int k ){

    int len = a.length;

    if (len == 0){
      return -1;
    }

    Arrays.sort(a);
    int count  = 0, left = 0, right = len -1; 

    while( left < right ){

        if ( a[left] + a[right] == k  ){

            count++; 

            if (a[left] == a[left+1] && left < len-1 ){
              left++;
            }

            if ( a[right] == a[right-1] && right >1 ){
              right-- ; 
            }

            right--; // right-- or left++, otherwise, will get struck in the while loop 
        }

        else if ( a[left] + a[right] < k ){
          left++;
        }

        else {
          right--;
        }
    }

    return count; 
}
公共静态int numberOfPairs(int[]a,int k){
int len=a.长度;
如果(len==0){
返回-1;
}
数组。排序(a);
整数计数=0,左=0,右=len-1;
while(左<右){
如果(a[左]+a[右]==k){
计数++;
if(a[left]==a[left+1]&&left1){
对--;
}
right--;//right--或left++,否则将在while循环中被击中
}
else if(a[左]+a[右]

此外,有人能提出其他解决问题的办法吗?谢谢。

您的解决方案过于复杂,您可以用更简单的方式进行此练习:

public static int numberOfPairs(int[] a, int k ){

    int count=0;
    List<Integer> dedup = new ArrayList<>(new HashSet<>(Arrays.asList(a)));
    for (int x=0 ; x < dedup.size() ; x++ ){
        for (int y=x+1 ; y < dedup.size() ; y++ ){
            if (dedup.get(x)+dedup.get(y) == k)
                count++;
        }
    }

    return count;
}
公共静态int numberOfPairs(int[]a,int k){
整数计数=0;
列表重复数据消除=新的ArrayList(新的哈希集(Arrays.asList(a));
对于(int x=0;x
这里的诀窍是让循环在第一个循环的索引之后开始,以不将相同的值计数两次,并且不将其与您自己的索引进行比较。此外,您还可以消除阵列中的重复数据以避免重复对,因为它们并不重要


您还可以对列表进行排序,然后在总和超过
k
时,立即中断循环,但这是一种优化。

以下解决方案将返回
唯一对的数量

public static int numberOfPairs(Integer[] array, int sum) {
    Set<Integer> set = new HashSet<>(Arrays.asList(array));

    // this set will keep track of the unique pairs.
    Set<String> uniquePairs = new HashSet<String>();

    for (int i : array) {
        int x = sum - i;
        if (set.contains(x)) {
            int[] y = new int[] { x, i };
            Arrays.sort(y);
            uniquePairs.add(Arrays.toString(y));
        }
    }

    //System.out.println(uniquePairs.size());
    return uniquePairs.size();
}
公共静态int numberOfPairs(整数[]数组,int和){
Set=newhashset(Arrays.asList(array));
//此集合将跟踪唯一对。
Set uniquePairs=新HashSet();
for(int i:array){
int x=总和-i;
if(集合包含(x)){
int[]y=新的int[]{x,i};
数组。排序(y);
添加(array.toString(y));
}
}
//System.out.println(uniquePairs.size());
返回uniquePairs.size();
}
时间复杂度将为O(n)


希望这有帮助。

给定一个整数数组和目标值,确定差等于目标值的数组元素对数。 该函数具有以下参数:

k:一个整数,目标差

arr:整数数组

使用LINQ这是一个很好的解决方案:

    public static int CountNumberOfPairsWithDiff(int k, int[] arr)
    {
        var numbers = arr.Select((value) => new { value });
        var pairs = from num1 in numbers
                    join num2 in numbers
                    on num1.value - k equals num2.value
                    select new[]
                {
                    num1.value, // first number in the pair
                    num2.value, // second number in the pair
                };
        foreach (var pair in pairs)
        {
            Console.WriteLine("Pair found: " + pair[0] + ", " + pair[1]);
        }

        return pairs.Count();
    }

您可以使用
HashMap
其中K:a[i]和V:K-a[i] 如果数组中存在重复项,则可能会导致错误答案

比如说:

int a[] = {4, 4, 4, 4, 4, 4, 4, 4, 4}
其中k=8或:

int a[] = {1, 3, 3, 3, 3, 1, 2, 1, 2}
其中k=4

所以为了避免这种情况,我们可以有一个
列表
,它可以检查每一对,看看它是否已经在列表中

static int numberOfPairs(int[] a, int k)
{
    List<List<Integer>> res = new ArrayList<>();
    Map<Integer, Integer> map = new HashMap<>();
    for(int element:a)
    {
        List<Integer> list = new ArrayList<>();
        if(map.containsKey(element))
        {
            list.add(element);
            list.add(map.get(element));
            if(!res.contains(list))
                res.add(list);
        }
        else
            map.put(k - element, element);        
    }
    return res.size();
}
静态int numberOfPairs(int[]a,int k)
{
List res=new ArrayList();
Map Map=newhashmap();
for(int元素:a)
{
列表=新的ArrayList();
if(映射容器(元素))
{
列表。添加(元素);
list.add(map.get(element));
如果(!res.contains(列表))
决议添加(列表);
}
其他的
map.put(k-元素,元素);
}
返回res.size();
}

重复元素可能是个问题,例如{3,3,2,1,45,27,6,78,9,0}我考虑过这一点,并提供了两个条件,如果k与该对匹配。如果(a[left]==a[left+1]&&left1{right--;}但是,你让我想想,可能有两个以上的数字是重复的,比如,int[]a={3,3,2,2,2,1,45,27,6,78,9,0},这里我有四个2。也许我应该像这样使用while,while(a[left]==a[left+1]&&left[1,2,1,2,1,2]
k=3
的示例数组,成对数应为9。您的解决方案返回1。我知道您的解决方案提到了一条注释,上面说
唯一对
,但是问题并没有指定元素是唯一的。