假设您已获得以下值的列表:
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解决,但我不确定如何实现它?
任何想法都将不胜感激!
答案 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)
,因此您可以
+4
和-4
差异1,5
和5,1
,您实际上是一对。作为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。