哈希表知识回顾
哈希表(Hash table,也叫散列表),是根据关键码值(Key value)而直接进行访问的数据结构。也就是说,它通过把关键码值映射到表中一个位置来访问记录,以加快查找的速度。这个映射函数叫做散列函数,存放记录的数组叫做散列表。
哈希冲突的解决方案:1.开放定制法 2.链地址法 3.公共溢出区法 4.再散列法
# 1 两数之和
给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那 两个 整数,并返回他们的数组下标。
你可以假设每种输入只会对应一个答案。但是,数组中同一个元素不能使用两遍。
题目链接:https://leetcode-cn.com/problems/two-sum/
给定 nums = [2, 7, 11, 15], target = 9
因为 nums[0] + nums[1] = 2 + 7 = 9
所以返回 [0, 1]
方法一:暴力两层遍历
// java
class Solution {
public int[] twoSum(int[] nums, int target) {
for(int i = 0; i < nums.length; i++){
for(int j = i+1; j < nums.length; j++){
if(nums[i] + nums[j] == target){
return new int[] {i,j};
}
}
}
throw new IllegalArgumentException("no two sum solution");
}
}
/**JavaScript
* @param {number[]} nums
* @param {number} target
* @return {number[]}
*/
var twoSum = function(nums, target) {
for(var i = 0; i < nums.length; i++){
var com = target - nums[i];
for(var j = i+1; j < nums.length; j++){
if(nums[j] == com){
return [i,j];
}
}
}
};
方法二:两遍哈希表
为了对运行时间复杂度进行优化,我们需要一种更有效的方法来检查数组中是否存在目标元素。如果存在,我们需要找出它的索引。保持数组中的每个元素与其索引相互对应的最好方法是什么?哈希表。哈希表支持以 近似 恒定的时间进行快速查找。
一个简单的实现使用了两次迭代。在第一次迭代中,我们将每个元素的值和它的索引添加到表中。然后,在第二次迭代中,我们将检查每个元素所对应的目标元素(target - nums[i]target−nums[i])是否存在于表中。注意,该目标元素不能是 nums[i]nums[i] 本身!
// java
class Solution {
public int[] twoSum(int[] nums, int target) {
Map<Integer, Integer> map = new HashMap<>(); // hash表声明
for(int i = 0; i < nums.length; i++){
map.put(nums[i], i); // 一次遍历将元素和其索引放入哈希表
}
for(int i = 0; i < nums.length; i++){ // 二次遍历找结果
int com = target - nums[i];
if(map.containsKey(com)&&map.get(com)!=i){
return new int[] {i, map.get(com)};
}
}
throw new IllegalArgumentException("no two sum result");
}
}
方法三:一遍哈希表
简化二遍哈希表。在进行迭代并将元素插入到表中的同时,我们还会回过头来检查表中是否已经存在当前元素所对应的目标元素。如果它存在,那我们已经找到了对应解,并立即将其返回。
// java
class Solution {
public int[] twoSum(int[] nums, int target) {
Map<Integer, Integer> map = new HashMap<>(); // 哈希表声明
for(int i = 0; i < nums.length; i++){
int com = targrt - nums[i];
if(maps.containsKey(com)){ // 哈希表里可以找到差值,直接返回
return new int[] {map.get(com),i}; // 注意顺序
}
map.put(nums[i],i); // 哈希表没有就将元素放入哈希表
}
throw new IllegalArgumentException("no two sum result");
}
}
/*Javascript*/
var twoSum = function(nums, target) {
const map = new Map();
for(let i = 0; i < nums.length; i++){
const com = target - nums[i];
if(map.has(com)){
return [map.get(com),i];
}else{
map.set(nums[i],i);
}
}
};