哈希表是根据关键码的值而直接进行访问的数据结构,比如数组就是一张哈希表(表中关键码就是数组的索引下标,然后通过下标直接访问数组中的元素)。
一般哈希表都是用来快速判断一个元素是否出现集合里。
如图所示,小李和小王都映射到了索引下标 1 的位置,这一现象叫做哈希碰撞。
var isAnagram = function(s, t) {
if(s.length !== t.length) return false;
// 数组也是一种hash结构
const arr = new Array(26).fill(0);
const base = 'a'.charCodeAt();
for (const x of s){
arr[x.charCodeAt() - base]++;
}
for (const x of t){
if(!arr[x.charCodeAt() - base]) return false;
arr[x.charCodeAt() - base]--;
}
return true;
};
var intersection = function(nums1, nums2) {
// 根据数组大小进行交换数组,将大一点的数组作为基准,一直将nums1作为大一点的数组
if (nums1.length < nums2.length) {
[nums1, nums2] = [nums2, nums1];
}
let set1 = new Set(nums1);
let set2 = new Set();
for (const x of nums2){
set1.has(x) && set2.add(x);
}
return Array.from(set2);
};
var isHappy = function(n) {
let m = new Map();
// 求n各个位上的数的平方和
const getSum = (n) => {
let sum = 0;
while (n){
sum += ((n % 10) * (n % 10));
n = Math.floor(n / 10);
}
return sum;
}
while (true){
// 如果出现了之前已经出现过的数,说明出现了死循环,就是false
if(m.has(n)) return false;
if(n === 1) return true;
m.set(n, 1);
n = getSum(n);
}
};
var twoSum = function(nums, target) {
let map = new Map();
for (let i = 0; i < nums.length; i++){
if(map.has(target - nums[i])) {
return [i, map.get(target - nums[i])];
} else {
map.set(nums[i], i);
}
}
};
var fourSumCount = function(nums1, nums2, nums3, nums4) {
let count = 0;
let twoMap = new Map();
for (let x of nums1) {
for (let y of nums2) {
// 可能不存在,所以隐式做一个判断
twoMap.set(x + y, (twoMap.get(x + y) || 0) + 1);
}
}
for (let x of nums3) {
for (let y of nums4) {
// 可能不存在,所以隐式做一个判断
count += (twoMap.get(-(x + y)) || 0);
}
}
return count;
};
var canConstruct = function(ransomNote, magazine) {
let arr = new Array(26).fill(0);
const base = 'a'.charCodeAt();
for (const x of magazine){
arr[x.charCodeAt() - base]++;
}
for (const x of ransomNote){
if(!arr[x.charCodeAt() - base]) return false;
arr[x.charCodeAt() - base]--;
}
return true;
};
var threeSum = function(nums) {
if(nums.length < 3) return [];
let res = [];
nums.sort((a, b) => a - b);
for(let i = 0; i < nums.length - 2; i++){
if(nums[i] > 0) break;
// a 去重
if (i > 0 && nums[i] === nums[i - 1]) continue;
let left = i + 1, right = nums.length - 1;
while (left < right){
let sum = nums[i] + nums[left] + nums[right];
if(sum > 0){
right--;
continue;
} else if(sum < 0){
left++;
continue;
} else {
res.push([nums[i], nums[left], nums[right]]);
}
// b c 去重
while (left < right && nums[left] === nums[++left]);
while (left < right && nums[right] === nums[--right]);
}
}
return res;
};
var fourSum = function(nums, target) {
const len = nums.length;
if(len < 4) return [];
nums.sort((a, b) => a - b);
const res = [];
for(let i = 0; i < len - 3; i++) {
// 去重i
if(i > 0 && nums[i] === nums[i - 1]) continue;
for(let j = i + 1; j < len - 2; j++) {
// 去重j
if(j > i + 1 && nums[j] === nums[j - 1]) continue;
let l = j + 1, r = len - 1;
while(l < r) {
const sum = nums[i] + nums[j] + nums[l] + nums[r];
if(sum < target) { l++; continue}
if(sum > target) { r--; continue}
res.push([nums[i], nums[j], nums[l], nums[r]]);
while(l < r && nums[l] === nums[++l]);
while(l < r && nums[r] === nums[--r]);
}
}
}
return res;
};