哈希表| 242.有效的字母异位词 、349. 两个数组的交集 、 202. 快乐数 、 1. 两数之和

📋目录

    ✅ 242.有效的字母异位词 

    ✅  349.两个数组的交集

    ✅  202.快乐数

    ✅  1.两数之和


242.有效的字母异位词(数组哈希)

⏰ 1.解题思路

  • 创建一个新数组,用来记录字符串中字符出现的次数---相当于将字符映射到数组也就是哈希表的索引下标上
  • 遍历第一个字符串,将出现的字符次数记录+1,关键代码's.charCodeAt(i) - "a".charCodeAt(i)'
  • 遍历第二个字符串,将出现的字符次数-1
  • 最后判断数组中元素值是不是都为0,如果不是则返回false

💻 2.代码

/**
 * @param {string} s
 * @param {string} t
 * @return {boolean}
 */
var isAnagram = function (s, t) {
  if (s.length !== t.length) return false;
  let arr = new Array(26).fill(0); //新建数组,每个元素的值为0
  let pivod = "a".charCodeAt(0); //97,不用特意去记ASCII,这里只需要相对位置,eg: "f".charCodeAt(0)=102,减去97,相对位置是5
  for (let i = 0, n = s.length; i < n; i++) {
    arr[s.charCodeAt(i) - pivod]++; //在arr[index]的数值上加1
    arr[t.charCodeAt(i) - pivod]--;
  }
  return arr.every((i) => i === 0); //返回的是一个布尔值
};

🍯 3.知识点补充

🍊  快速判断一个元素是是否出现在集合中,就要想到用哈希法来解决问题。

🍒  常见的3种哈希表的数据结构,适用范围

    • 数组:简单的hash表,哈希值小,范围可控
    • set:数据结构大
    • map:数据结构法,并且key有对应的value值

         🍇 String.prototype.charCodeAt() 方法返回的 0 65535 之间的整数

             eg:   "a".charCodeAt(0) = 97 是它的ASCII码

         🍓 Array.prototype.every() 方法返回的是一个布尔值,是测试一个数组内的所有元素是否都能通过指定函数的测试。

             eg: arr.every((i) => i === 0)   //测试的就是这个数组中是不是所有元素都是0

 

 


349.两个数的交集(set哈希)

⏰ 1.解题思路

  • 先比较两个数组的大小,将长度较长的数组存到哈希表。
  • 遍历短的数组,判断哈希表中是否存在长数组中。

💻 2.代码

/**
 * @param {number[]} nums1
 * @param {number[]} nums2
 * @return {number[]}
 */
var intersection = function(nums1, nums2) {
    //判断数组大小
    if(nums1.length < nums2.length){
        let _ = nums1;
        nums1 = nums2;
        nums2 = _;
    }
    const nums1Set = new Set();
    //结果是数组中的每一个元素都是唯一的,所以也创建一个哈希表
    const resSet = new Set();
    for (let i = 0; i< nums2.length; i++){
        nums1Set.has(nums2[i]) && resSet.add[nums2[i]]
    }
    return Array.from(resSet);
};

🍯 3.知识点补充

🍊  如果哈希值比较少、特别分散、跨度非常大,使用数组就造成空间的极大浪费!

🍒 Array.from() 方法 静态方法从可迭代类数组对象创建一个新的浅拷贝的数组实例。

 

 


     

202.快乐数(set哈希)

⏰ 1.解题思路

  • 抓住重点,最后结果就是,这个变成1或者重复出现,也就是题目中的无限循环。
  • 哈希表中的每一个元素都是唯一的。

💻 2.代码

/**
 * @param {number[]} nums1
/**
 * @param {number} n
 * @return {boolean}
 */
var getSum = function (n) {
    //获取sum 
    let sum = 0;
    while(n){
    sum += (n % 10) ** 2  //取个位数,并且平方,累加
        //取剩下的各个数,再进入循环,取个位数,直到最后一位数。
        //最后一位数的取值[1,9],除10向下取整,都会等于0,此时就可以跳出循环。
        n = Math.floor(n / 10) 
    }
    return sum
}
var isHappy = function(n) {
    const set = new Set();
    while(n !== 1 && !set.has(n)){
        set.add(n);
        n = getSum(n);
    }
    return n === 1;
};

 

 

 


1.两数之和(map哈希)

⏰ 1.解题思路

  • 创建一个map存放,已经访问过的数组。
  • 遍历数组,向map去查询是否有和当前元素匹配的数值,如果有,就返回下标,没有就把当前遍历的元素放进map中。

💻 2.代码

/**
 * @param {number[]} nums1
/**
 * @param {number[]} nums
 * @param {number} target
 * @return {number[]}
 */
var twoSum = function (nums, target) {
  let map = new Map();
  let resArr = [];
  for (let i = 0; i < nums.length; i++) {
    let index = map.get(target - nums[i]);
    if (index !== undefined) {
      resArr = [index, i];
    }
    map.set(nums[i], i); //将没有匹配到,但是已经遍历的元素存到map中
  }
  return resArr;
};

🍯 3.知识点补充

🍊  快速判断一个元素是是否出现在集合中,就要想到用哈希法来解决问题。

🍒  常见的3种哈希表的数据结构,适用范围(重新总结

    • 数组:简单的hash表,范围可控,哈希值太大会造成内存空间的浪费
    • set:数据结构大,存放的元素只能是一个key。
    • map:map是一种key value的存储结构,用key保存数值,用value保存数值所在的下标
posted @ 2023-04-25 17:35  karen哈哈哈  阅读(11)  评论(0编辑  收藏  举报