在O(n)

时间:2016-08-11 03:07:53

标签: java arrays algorithm

包含重复项[4,4,1]的数组。在5中查找总和为O(n)的货币对。 预期输出(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)中找到解决方案吗?

3 个答案:

答案 0 :(得分: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;
}

答案 1 :(得分:1)

你也可以试试这个

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;

答案 2 :(得分:0)

这是使用 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)