簡體   English   中英

在 O(n) 中找到重復項的數組中的和對

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

具有重復項[4,4,1]數組。 O(n)找到總和為5對。 預期輸出(4,1)(4,1)和計數為2

方法#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; 
    }

輸出為1

鏈接中所述的方法#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;
    }

輸出1

然而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;
  }

我們能得到O(n)的解決方案嗎?

您可以使用第二種方法 - 只需將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;
}

你也可以試試這個

Map<Integer, List> map = new HashMap<>(); 整數計數 = 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;

這是使用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));
    }
}

輸出:
2 (對)

(4,1) (4,1)

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