给定N个元素的数组A []和数字x,检查A []中的对,其中和为x?
方法1 =排序给出O(n lg n)。
方法2 =使用给出O(n)的哈希表。
我在方法2中有一个疑问,即如果使用链接,那么对于每个元素我们必须在列表中搜索其补码,在最坏的情况下由于链接可以产生O(n ^ 2)。
我认为只有在给出整数范围时它才会起作用,因此我们可以在没有链接的情况下使用哈希表来给出O(n)。我对吗 ?
您可以尝试以下方法 - >
hash all elements in A[], like (key, value) = (A[i],true)
for all elements in A[]:
if hash(x-A[i])=true: it exists
你对哈希表是正确的,O(n)不是最坏情况保证的复杂性。但是,使用合理的散列函数,最坏的情况应该很少发生。
当然,如果在数字范围上给出足够小的上限,则可以使用普通数组来完成这一操作。
O(N)解决方案使用hashmap来维持元素Vs的频率。保持频率以使其适用于重复数组元素的情况。
public static boolean countDiffPairsUsingHashing(int[] nums, int target) {
if (nums != null && nums.length > 0) {
HashMap<Integer, Integer> numVsFreq = new HashMap<Integer, Integer>();
for (int i = 0; i < nums.length; i++) {
numVsFreq.put(nums[i], numVsFreq.getOrDefault(nums[i], 0) + 1);
}
for (int i = 0; i < nums.length; i++) {
int diff = target - nums[i];
numVsFreq.put(nums[i], numVsFreq.get(nums[i]) - 1);
if (numVsFreq.get(diff) != null && numVsFreq.get(diff) > 0) {
return true;
}
numVsFreq.put(nums[i], numVsFreq.get(nums[i]) + 1);
}
}
return false;
}