简体   繁体   English

在 O(n) 中找到重复项的数组中的和对

[英]Find a sum pair in array with duplicates in O(n)

Array with duplicates [4,4,1] .具有重复项[4,4,1]数组。 Find pairs with sum 5 in O(n) .O(n)找到总和为5对。 Expected output (4,1) and (4,1) and count is 2 .预期输出(4,1)(4,1)和计数为2

Approach#1: Using HashSet :方法#1:使用HashSet

public static int twoSum(int[] numbers, int target) {
    HashSet<Integer> set = new HashSet<Integer>();
    int c = 0;
    for(int i:numbers){
      if(set.contains(target-i)){
        System.out.println(i+"-"+(target-i));
        c++;
      }
      set.add(i);
    }
     return c; 
    }

Output is 1 .输出为1

Approach #2 as stated in this link :链接中所述的方法#2:

private static final int MAX = 100000; 

    static int printpairs(int arr[],int sum)
    {
      int count = 0;
        boolean[] binmap = new boolean[MAX];
        for (int i=0; i<arr.length; ++i)
        {
            int temp = sum-arr[i];
            if (temp>=0 && binmap[temp])
            {
                count ++;
            }
            binmap[arr[i]] = true;
        }
      return count;
    }

Output 1 .输出1

However the O(nlog n) solution is using sorting the array:然而O(nlog n)解决方案是使用对数组进行排序:

 public static int findPairs(int [] a, int sum){

    Arrays.sort(a);
    int l = 0;
    int r = a.length -1;
    int count = 0;
    while(l<r){

      if((a[l] + a[r]) == sum){
         count ++;
        System.out.println(a[l] + " "+ a[r]);
        r--;
      }
      else if((a[l] + a[r])>sum ){
        r--; 
      }else{
        l++;
      }
    }
    return count;
  }

Can we get the solution in O(n) ?我们能得到O(n)的解决方案吗?

You can use your second approach - just change boolean to int :您可以使用第二种方法 - 只需将boolean更改为int

public static void main(String[] args) {
    System.out.println(printPairs(new int[]{3, 3, 3, 3}, 6)); // 6
    System.out.println(printPairs(new int[]{4, 4, 1}, 5)); // 2
    System.out.println(printPairs(new int[]{1, 2, 3, 4, 5, 6}, 7)); // 3
    System.out.println(printPairs(new int[]{3, 3, 3, 3, 1, 1, 5, 5}, 6)); // 10
}

public static int printPairs(int arr[], int sum) {
    int count = 0;
    int[] quantity = new int[sum];
    for (int i = 0; i < arr.length; ++i) {
        int supplement = sum - arr[i];
        if (supplement >= 0) {
            count += quantity[supplement];
        }
        quantity[arr[i]]++; // You may need to check that arr[i] is in bounds
    }
    return count;
}

you can try this also你也可以试试这个

Map<Integer, List> map = new HashMap<>(); Map<Integer, List> map = new HashMap<>(); int count = 0;整数计数 = 0;

    for (int i = 0; i < arr.length; i++) {

        if (map.containsKey(k - arr[i])) {
            count += map.get(k - arr[i]).size();
        }
        List<Integer> test = map.getOrDefault(arr[i], new ArrayList<>());
        test.add(i);
        map.put(arr[i], test);
    }
    
    return count;

Here is an O(N) Time & Space approach using HashMap .这是使用HashMapO(N)时间和空间方法。

class Solution
{
    static int getPairsCount(int[] arr, int n, int target)
    {
        HashMap<Integer,Integer> map = new HashMap<>();
        int pairs=0;
        for (int i=0; i<n; i++)
        {
            if (map.containsKey(target - arr[i]))
            {
                pairs += map.get(target - arr[i]);
                for (int j=1; j<=map.get(target - arr[i]); j++)
                    System.out.print("(" +(target-arr[i])+ "," +arr[i]+ ") ");
            }
            map.put(arr[i] , map.getOrDefault(arr[i],0)+1);
        }
        return pairs;
    }
    public static void main (String [] args)
    {
        int target = 5;
        int [] input = {4, 4, 1};
        System.out.println(getPairsCount(input , input.length , target));
        target = 10;
        input = new int [] {1, 6, 3, 2, 5, 5, 7, 8, 4, 8, 2, 5, 9, 9, 1};
        System.out.println(getPairsCount(input , input.length , target));
    }
}

Output:输出:
2 (Pairs) 2 (对)

(4,1) (4,1)

13 (Pairs) 13 (对)

(5,5) (3,7) (2,8) (6,4) (2,8) (8,2) (8,2) (5,5) (5,5) (1,9) (1,9) (9,1) (9,1)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM