代码随想录算法训练营第六天242.有效的字母异位词、349. 两个数组的交集、第202题. 快乐数、1. 两数之和、第202题. 快乐数

今天是哈希表练习的第一天:

首先复习了哈希表的理论基础:

哈希表是根据关键码的值直接进行访问的数据结构,一般解决的问题是判断一个元素是否出现在集合中,有数组,map和set这几种

如果hashCode得到的数值大于tableSize,那么就要对数组进行一个取模操作,通过哈希函数来映射到哈希表的索引;

如果发生了哈希碰撞(即两个名字都被链接到了同一个index, 那么需要用其他方法来解决问题 (拉链法和线性探索法)

因为我们要使用额外的数组,set或者是map来存放数据,才能实现快速的查找。

242JS代码实现

var isAnagram = function (s, t) {
  let letterArray = new Array(26).fill(0);
  const base = 'a'.charCodeAt() // js这里求unicode要用charCodeAt

  for (let i = 0; i < s.length; i = i + 1) {
    letterArray[s[i].charCodeAt() - base]++;
  }
  for (let j = 0; j < t.length; j = j + 1) {
    letterArray[t[j].charCodeAt() - base]--;
  }

  for (let k = 0; k < 26; k++) {
    if (letterArray[k] !== 0) {
      return false;
    }
  }
  return true;
};

242. 有效的字母异位词

题目链接:. - 力扣(LeetCode)

哈希表的结构因为平常用到的比较多,相对会熟悉一点;

这道题我的思路是:
1. 用一个哈希表去存s的每一个字符的次数,得到s的里面每个字母的出现次数
2. 再用这个哈希表判断是否存在t里面的字母,将t字母每次出现的字母-1,
3. 如果这个哈希表最后每个字母对应的值都为0的话,则为一个字母异位词
4. 这个解法的空间复杂度为O(n + m), 这个解法的时间复杂度为O(n + m))

实现代码如下: 

function areAnagrams(s, t) {
    const map = new Map();

    // 统计字符串 s 中每个字符出现的次数
    for (let i = 0; i < s.length; i++) {
        const char = s[i];
        map.set(char, (map.get(char) || 0) + 1);
    }

    // 在字符串 t 中减去字符出现的次数
    for (let j = 0; j < t.length; j++) {
        const char = t[j];
        if (!map.has(char)) {
            return false; // 如果 t 中出现了 s 中没有的字符,则不是字母异位词
        }
        map.set(char, map.get(char) - 1);
        if (map.get(char) === 0) {
            map.delete(char); // 如果字符的次数减到 0,则从 Map 中删除
        }
    }

    // 如果 Map 不为空,则表示有字符在 s 中但不在 t 中,或者在 t 中但不在 s 中
    return map.size === 0;
}

卡哥思路: 有些方法需要基础知识掌握的比较牢固;因为这两个字符串都是由字母组成的,字母a-z对应的ASCII码是连续的,那么如果拿这个字母去减去a,就可以对应到数组的索引。

另外卡哥提到:一般哈希法可以先想想能不能用数组,但是数据量比较大的时候,就不适合用数组了。先要考虑数组,因为速度是最快的。

369.两个数组的交集

题目链接: . - 力扣(LeetCode)

我的思路:
1. 本来想根据有效的字母异位词改一改,根据长数组来判断短数组中是否存在相对应的值,但是长数组里面可能存在重复的值,那用map来统计次数则不对了,
2. 则通过遍历长数组,将其值映射成map的形式,再遍历短数组,如果map中有相对应的key,则证明其为相交值,则push进入result
3. 还有一点,如果短数组中有重复项的话,那result也会重复,所以保证唯一性的话,应该开始就用Set去定义

var intersection = function (nums1, nums2) {
    let length1 = nums1.length;
    let length2 = nums2.length;
    let setNum1 = new Set(nums1);
    let setNum2 = new Set(nums2);
    let longArr = length1 > length2 ? setNum1 : setNum2;
    let shortArr = length1 > length2 ? setNum2 : setNum1;
    let result = [];

    console.log("short", longArr, shortArr);

    for (let num of longArr) {
        if (shortArr.has(num)) {
            result.push(num);
        }
    }
    return result;
};

卡哥思路:

上一题提过如果可以用哈希表,那么可以优先考虑数组;并且乐扣设定了 num 的长度在 1000 以下,数据量较少的情况下适合用数组,数组操作更快

数组方式的实现代码:

var intersection = function(nums1, nums2) {
    let lengthArray = new Array(1005).fill(0)
    let result = []
    for(let i = 0; i < nums1.length; i++) {
        lengthArray[nums1[i]] = 1
    } 
    for(let j = 0; j < nums2.length; j++) {
        if(lengthArray[nums2[j]] === 1) {
            result.push(nums2[j])
        }
    }
    return Array.from(new Set(result))
};

202.快乐数

题目链接:. - 力扣(LeetCode)

我的思路:

用一个set来存得出的位数平方的和, 如果在set中能找到当前数得出的平方和,那么则会陷入无限循环;则返回 false,那么用 while 循环判断是否是进入无限循环

const getSum = (n) => {
    let sum = 0;
    while (n) {
        sum = sum + (n % 10) * (n % 10)
        n = Math.floor(n / 10)
    }
    return sum
}

var isHappy = function(n) {
    let set = new Set()
    while(true) {
        if(set.has(n)) return false
        if(n === 1) return true
        set.add(n)
        n = getSum(n) // 下一次的 n 是各位数求和之后的值
    }

};

1. 两数之和

题目链接:. - 力扣(LeetCode)

思路:用一个 map 来存 索引(key)和 target 和当前索引对应的差值(value),然后遍历数组,如果当前索引不是一样的,且和差值相等,则得到两个数

   let map = new Map()
    for(let i = 0; i < nums.length; i++) {
        map.set(target - nums[i], i)
    } 

    for(let j = 0; j < nums.length; j++) {
        if(map.get(nums[j]) && j !== map.get(nums[j])) {
            return [map.get(nums[j]), j]
        }
    }
    return []

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值