查找总和为整数的不同整数对的数量

时间:2016-12-30 12:53:54

标签: java hash count combinations

我正在尝试计算数组中的对数,以便每对给出一个整数的总和!

我使用了以下代码:

    public static int SumPairs(Integer []input, int k){
    Map<Integer, Integer> pairs = new HashMap<Integer, Integer>();
    int tmp=0;
    //System.out.println(pairs.toString());
     for(int i=0;i<input.length;i++){
     if(pairs.containsKey(input[i])){
            System.out.println(pairs.containsKey(input[i]));
             System.out.println(input[i] +", "+ pairs.get(input[i]));
             input[i]=0; 
            tmp++;      

        }

        else
            pairs.put(k-input[i], input[i]);
    }return tmp;
}

问题是;例如,当我的数组是1 2 2 2 3 4 4 4时 和sum = 5 它计算如下

(4,1)
(4,1)
(4,1)
(3,2)

我想阻止该方法多次使用一个数字!! 所以输出将是

(4,1)
(3,2)

12 个答案:

答案 0 :(得分:1)

我使用存储值及其频率的地图:

public static int SumPairs(Integer[] input, int k){
    Map<Integer, Integer> frequencies = new HashMap<>();
    int pairsCount = 0;      

    for(int i=0; i<input.length; i++){
        int value = input[i];
        int complement = k - input[i];

        if(frequencies.containsKey(complement)){                
            int freq = frequencies.get(complement) - 1;
            pairsCount++;
            //System.out.println(value + ", " + complement);    
            if(freq == 0){
                frequencies.remove(complement);
            }else{
                frequencies.put(complement, freq);
            }
        }else{
            if(frequencies.containsKey(value)){         
                frequencies.put(value, frequencies.get(value) + 1);             
            }else{
                frequencies.put(value, 1);
            }
        }
    }
    return pairsCount;
}

答案 1 :(得分:1)

我希望这可以帮助

def numberOfPairs(a, k):

    # Let's do a o(n) approach by maintaining all the compliments of the K in a 
    # visited set

    compliments = set()
    result = []
    for v in a:
        # See if the element is in the compliments set, if so thats the pair
        if v in compliments:
            result.append((v, k-v))
        # If the element is not found in visited save the compliment of it in the visited set    
        else:
            compliments.add(k-v)


    if len(result) == 1 or len(result) == 0:
        return len(result)

    # Now lets get the distinct pairs 

    result.sort()
    prev = result[0]
    distinct = []
    for r in result:
        if len(set(r) - set(prev)) > 0:
            distinct.append(prev)
            distinct.append(r)
        prev = r

    if len(distinct) == 0:
        return 1
    else:
        return  len(distinct)  

答案 2 :(得分:0)

  

代码采用一个数组,并返回所有具有指定总和的可能对。由于该问题要求打印的是对数,而不是对,因此数组长度除以2即可得到所需的答案。

int notInArray(float a[],float m,int n)
{
   int i,j,k;
   for(i=0;i<n;i++)
   {
       if(a[i] == m)
           return 0;
   }
   return 1;


}
int main() {

   int i,j,k;
   int n;
   scanf("%d",&n);   //Input the number of elements in array.

   float arr[n];

   for(i=0;i<n;i++)
       scanf("%f",&arr[i]);   //input the array elements


   float copyArr = arr[0];

   float m;

   if (n == 0)
       return 0;

   scanf("%f",&m);   //input the sum

   float resArr[n];
   int b;
   int a=b=0;

   for(i=0;i<n;i++)
   {
       for(j=i+1;j<n;j++)
       {
           if(arr[i]+arr[j]==m && notInArray(resArr,arr[i],n))
           {
               resArr[a++] = arr[i];
               resArr[a++] = arr[j];

               //printf("%.0f %.0f\n",arr[i],arr[j]);
           }
       }
   }

   printf("All possible pairs: \n");
   for(i = 0;i<a;i+=2)
       printf("%.0f %.0f\n",resArr[i],resArr[i+1]);

   int len = (int)( sizeof(resArr) / sizeof(resArr[0]) )
   printf("Number of such pairs: %d",len);
   return 0;
}

答案 3 :(得分:0)

    public void distinctPairs(int[] arr, int k){
    int length = arr.length;
    int count = 0;
    Map<Integer,Integer> pairs = new HashMap<Integer,Integer>();
    for(int i=0;i<length;i++){
        for(int j=i+1;j<length;j++){
            if(arr[i]+arr[j] == k ){
                if(!(pairs.containsKey(arr[j])&&pairs.containsValue(arr[i]))) 
                pairs.put(arr[i], arr[j]);
            }
        }
    }
    count = pairs.size();
    System.out.println("Pairs are "+pairs+"  count  = "+count);
}

这对我有用。我遵循的步骤。

  1. 检查对的总和是否等于required(k)。
  2. 检查该配对是否在地图中不存在。

答案 4 :(得分:0)

我们可以使用哈希图存储数组的所有值。然后遍历数组,并检查映射是否包含(K-a [i])。如果地图包含增量计数,则从地图中删除两个键。

private int getDistinctPair(int k,int[] input){
        HashMap<Integer,Integer> map = new HashMap<>();
        int pairs = 0;
        for (int i = 0; i < input.length-1; i++) {
            map.put(input[i], input[i]);
        }
        for (int i = 0; i <input.length-1 ; i++) {
            int diff = k - input[i];
            if(map.containsKey(diff)){
                pairs++;
                map.remove(diff);
                map.remove(input[i]);
            }
        }
        return  pairs;
    }

答案 5 :(得分:0)

这适用于我能想到的所有测试用例。请在注释部分添加此代码失败的任何测试用例,以便我进行修复。如果可行,请接受解决方案。

public class DistinctPairs {

    private static int count(int target, int... arr) {
        int count = 0;
        Set<String> seen = new HashSet<>();
        Set<Integer> set = new HashSet<>();
        for (int i = 0; i < arr.length; i++) {
            int k = target - arr[i];
            int[] pair = new int[]{k, arr[i]};
            Arrays.sort(pair);
            String s = Arrays.toString(pair);
            if (set.contains(k) && !seen.contains(s)) {
                count++;
                seen.add(s);
                // uncomment this print statement to print the distinct pairs
                // System.out.println(s);
            } else {
                set.add(arr[i]);
            }
        }
        return count;
    }

    // test suite and driver method
    public static void main(String[] args) {
        System.out.println(count(10, 1, 2, 3, 6, 7, 8, 9, 1) == 3);
        System.out.println(count(47, 6, 1, 3, 46, 1, 3, 9) == 1);
        System.out.println(count(9, 3, 2, 1, 45, 27, 6, 78, 9, 0) == 2);
        System.out.println(count(9, 3, 3, 2, 1, 45, 27, 6, 78, 9, 0) == 2);
        System.out.println(count(6, 1, 5, 7, -1) == 2);
        System.out.println(count(6, 1, 5, 7, -1, 5) == 2);
        System.out.println(count(2, 1, 1, 1, 1) == 1);
        System.out.println(count(5, 1, 2, 2, 2, 3, 4, 4, 4) == 2);
        System.out.println(count(8, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4) == 1);
        System.out.println(count(7, 1, 5, 66, 2, 3, 4, 7, 0, 2, 5) == 3);
        System.out.println(count(5) == 0);            
        System.out.println(count(5, 1) == 0);
        System.out.println(count(7, 3, 4) == 1);
    }
}

另一种方法可能是遵循经典的“两个和问题”的解决方案,并在找到对时将它们添加到集合中,所有这些都在同一遍中完成。该集合将是一个具有arr [i]和(target-arr [i])作为其成员的自定义包装类,并且您需要以(a,b)的方式重写hashcode()和equals()方法)与(b,a)相同。最后,只需返回集合的大小即可。与第一种方法相比,此方法在Big-O方面将具有相同的时间和空间复杂度。

int count(int target, int... nums) {
    Set<Pair> uniPairs = new HashSet<>();
    Set<Integer> seen = new HashSet<>();
    for (int i = 0; i < nums.length; i++) {
        int diff = target - nums[i];
        if (seen.contains(diff)) {
            Pair pair = new Pair(nums[i], diff);
            uniPairs.add(pair);
        }
        seen.add(nums[i]);
    }
    return uniPairs.size();
}

class Pair {
    int a;
    int b;
    public Pair (int a, int b) {
        this.a = a;
        this.b = b;
    }

    @Override
    public boolean equals(Object obj) {
        Pair pair2 = (Pair) obj;
        return ((a == pair2.a) && (b == pair2.b)) || ((b == pair2.a) && (a == pair2.b));
    }

    @Override
    public int hashCode() {
        return Objects.hash(a, b) + Objects.hash(b, a);
    }
}

答案 6 :(得分:0)

您可以使用以下代码进行修改:

def countPairs(arr, k):
    possible_maps = []

    for num in arr:
        pair_matches = list(filter(lambda n: n + num == k, arr))

        if len(pair_matches) > 0:
            possible_maps += list(map(lambda nm: (num, nm), pair_matches))

    return len(set(map(lambda pair: ','.join(str(n) for n in sorted(pair)), possible_maps)))

希望这对您有所帮助。

答案 7 :(得分:0)

我的C#方法在一个循环中仅用另一个列表来存储临时的diff值。

        private static int SumPairs(int[] arr, int sum)
        {
            Dictionary<int, int> frequency = new Dictionary<int, int>();
            List<int> temp = new List<int>();
            int count = 0;

            foreach (int i in arr)
            {
                int diff = sum - i;

                if (!frequency.ContainsKey(i))
                {
                    if (temp.Contains(i))
                    {
                        frequency.Add(i, diff);
                        count++;
                    }
                    else
                    {
                        temp.Add(diff);
                    }
                }
            };

            return count;
        }

答案 8 :(得分:0)

使用Tuple

的C#实现
static List<Tuple<int,int>> GetUniquePairs(int[] arr, int sum)
        {
            Dictionary<Tuple<int, int>, int> kvp = new Dictionary<Tuple<int, int>, int>();
            List<Tuple<int,int>> result = new List<Tuple<int,int>>();
            int length = arr.Length;
            for(int i = 0;i < length; i++)
            {
                int j = i + 1;
                while (j < length)
                {
                    if(arr[i]+arr[j] == sum)
                    {
                        Tuple<int, int> key = new Tuple<int, int>(arr[i], arr[j]);
                        if (!kvp.ContainsKey(key))
                            kvp.Add(key, 1);
                    }

                    j++;
                }
            }

            var keys = kvp.Keys;
            foreach(var k in keys)
            {
                result.Add(k);
            }
            return result;
        }

答案 9 :(得分:-1)

public static int sumPairs(Integer[] input, int sum){
    List<Integer> complementaries = new ArrayList<>(input.length);
    int pairs = 0;
    for(Integer number : input){
        if(complementaries.contains(number)){
            complementaries.remove(number);
            pairs++;
        }
        else{
            complementaries.add(sum-number);
        }
    }
    return pairs;
}

现在它应该完美无缺。

互补数组仅用于跟踪总和所需的数字。如果它包含数字,则意味着我们之前迭代了它的互补,所以我们可以添加一对并从互补列表中删除该数字。另外,我们将当前数字的补充添加到列表中,而不是使用对计数器。

答案 10 :(得分:-1)

找到不同对的问题的最简单解决方案:

public static int SumPairs(int[] input, int k) {

    Map<Integer, Integer> pairs = new HashMap<Integer, Integer>();
    int tmp = 0;
    for (int data : input) {
        if (pairs.containsKey(k - data) && pairs.get(k - data) == 0) {
            tmp++;
            pairs.put((k - data), pairs.get(k - data) + 1);
        } else if (!pairs.containsKey(data)) {
            pairs.put(data, 0);
        }
    }

    return tmp;
}

已经测试 1 2 2 2 3 4 4 4和sum = 5 。也适用于 4 4 4 4 4 4 4 4 4 4 4 4 4 4和sum = 8 。 如果有任何困惑,请随时问我。欢呼声。

答案 11 :(得分:-1)

import java.util.HashSet;
public class DistinctPairs {     
   static int numberOfPairs(int[] arr,int k)
   {
       HashSet<String> s=new HashSet<String>();
       int n=arr.length;
       int sum=0;
       for(int i=0;i<n;i++)
       {
           for(int j=0;j<n;j++)
           {
               sum=arr[i]+arr[j];
               if(i==j)
               {
                   continue;
               }
               else
               {
                  if(sum==k)
                  {
                      String l=String.valueOf("("+arr[i]+","+arr[j]+")");
                      StringBuilder sb=new StringBuilder(l);
                      String rl=sb.reverse().toString();
                      if(s.add(l)==false)
                      {

                      }

                  }
               }

           }
       }
        System.out.println(s.toString());

       return s.size()/2;
   }
    public static void main(String args[])
    {
        int b[]={1,5,66,2,3,4,7,0,2,5};
     int size=numberOfPairs(b,5);  
     System.out.println(size);
    }
}