如何使用hashmaps解决这个问题?

时间:2015-10-18 17:32:10

标签: java arrays algorithm data-structures hashmap

假设您已获得以下值的列表:

k=4

并且您认为k k是两个数组元素之间的区别。您如何找到k出现的次数?例如,在此列表[(5-1),(8-4),(9-5)]中出现3次O(n^2)

我能够使用两个for循环来解决这个问题,但这需要Sardine sardine = SardineFactory.begin("username", "password"); sardine.enablePreemptiveAuthentication("webdav/"); InputStream is = sardine.get("file");次。我听说这可以用hashmaps解决,但我不确定如何实现它?

任何想法都将不胜感激!

5 个答案:

答案 0 :(得分:3)

想法是存储k和输入数组中每个值之间的所有可能差异(numbers)。 然后计算输入数组中符合差异的值的数量。

这将有效:

public class Solution {
    public int twoSum(int[] numbers, int k) {
        if (numbers == null) {
            return null;
        }
        int count = 0;
        HashMap<Integer, Integer> difference = new HashMap<Integer, Integer>();
        for (int i = 0; i < numbers.length; i++) {
            difference.put(k - numbers[i], i);
        }
        for (int i = 0; i < numbers.length; i++) {
            int cur = -numbers[i];
            if (difference.containsKey(cur) && difference.get(cur) != i) {
                count++;
            }
        }
        return count;
    }
}

要抓住difference.get(cur) != i条件(i是索引cur),以避免出现k = 0并且每个值都会形成一对与自己。

答案 1 :(得分:2)

使用HashSet(内部使用HashMap),我们可以假设其contains方法接近O(1),因此您可以

  1. 用所有元素填充这样的集合
  2. 迭代元素并计算+4-4差异
  3. 的值
  4. 检查这些值是否存在于集合中。
  5. 将结果除以2,因为对于成对1,55,1,您实际上是一对。
  6. 作为shown by Óscar López,您只需计算+4-4中的一个并跳过最后一步即可改进它

答案 2 :(得分:2)

事实上,只需使用Set即可解决:我们必须找到该集合是否包含与k中当前结果不同的另一个元素。尝试以下解决方案,它假设输入中至少有两个元素没有重复,并且不会浪费空间用于不需要的值,如果我们使用HashMap这样的情况就是这种情况问题:

int k = 4;
int howMany = 0;
Set<Integer> set = new HashSet<>(Arrays.asList(1, 4, 5, 7, 8, 9));

System.out.printf("k = %d%n", k);   

for (Integer n : set) {
    if (set.contains(n - k)) {
        howMany++;
        System.out.printf("(%d - %d) = k%n", n, n - k);
    }
}

System.out.printf("k appears %d times%n", howMany);

以上结果如下:

k = 4
(5 - 1) = k
(8 - 4) = k
(9 - 5) = k
k appears 3 times

答案 3 :(得分:1)

即使数组包含重复项,以下方法仍然有效。它实现了Pshemo的最终算法(没有重复的工作,没有2的除法)。

首先,它将原始数组的内容存储在hashmap中。原始值是键,原始值在数组中出现的次数是hashmap的值。此阶段具有运行时O(原始列表中的项目数),并使用存储O(原始列表中的不同项目数)。

其次,它loops through the hashmap,并找到(delta = 4)大于正在考虑的项目的任何项目。它做了一些数学运算来增加结果。它有一个处理(delta == 0)场景的特殊情况,以处理凌中提到的问题。此阶段具有运行时O(原始列表中不同项的数量)。

public class Solution {
    public int countDifferences(int delta, int[] array) {
        if (array == null) {
            return 0;
        }
        // Load the contents of the array into a hashmap.
        // This process loses the sorting.
        HashMap<Integer, Integer> choices = new HashMap<>();
        for (int arrayItem : array) {
            if (choices.containsKey(arrayItem)) {
                choices.put(arrayItem, 1 + choices.get(arrayItem));
            } else {
                choices.put(arrayItem, 1);
            }
        }

        // Count the result.
        int result = 0;
        for(Map.Entry<Integer, Integer> e : choices.entrySet()) {
            Integer key   = e.getKey();
            Integer value = e.getValue();
            if (delta == 0) {
                result += value * (value - 1) / 2; // add summorial(value - 1)
            } else {
                if (choices.containsKey(key + delta)) {
                    result += value * choices.get(key + delta);
                }
            }
        }
        return result;
    }
}

答案 4 :(得分:0)

您可以在单次迭代中实现此目的。 像这样应用逻辑,当开始迭代时说假设你有一个带有k,v对的hashmap 防爆。 1,dummyvalue 4,dummyvalue 5,虚拟值

假设你的k = 4 因此,当开始迭代地图时,你会先说1,所以就像1 + k,即1 + 4,即5,所以回顾你的数据结构或映射为key = 5 map.get(5)如果map返回值更新另一个地图或另一个数据结构保持你的数量ok k说假设我们有一个k = 4的地图所以如果我们得到这里的密钥是4,那么它的值将是这样的一个count = count +1。