【问题标题】:Find a sum pair in array with duplicates in O(n)在 O(n) 中找到具有重复项的数组中的和对
【发布时间】:2016-08-11 03:07:53
【问题描述】:

重复数组[4,4,1]。在 O(n) 中找到 sum 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

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

输出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) 中获得解决方案吗?

【问题讨论】:

  • 在方法 #2 中是什么阻止您将 boolean[] 更改为 int[]
  • @user3707125 将boolean[] 更改为int[] 有何不同?
  • 方法#3 是有效的。只需在 O(n) 时间内使用数组排序,而不是在 O(nlg(n) 时间使用数组排序,这当然假设您可以在输入上使用基数或计数排序(使用给定的整数范围,您可以) .
  • 我认为方法 #1 需要在 for 循环之前填充 HashSet 才能工作。

标签: java arrays algorithm


【解决方案1】:

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

【讨论】:

    【解决方案2】:

    你也可以试试这个

    Map 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;
    

    【讨论】:

      【解决方案3】:

      这是一个使用 HashMapO(N) Time & Space 方法。

      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)
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-11-28
        • 1970-01-01
        • 1970-01-01
        • 2013-02-03
        • 2011-08-09
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多