代码随想录算法训练营Day6|哈希表理论基础、242.有效的字母异位词、349.两个数组的交集、202.快乐数、1.两数之和

一、哈希表理论基础

哈希表是根据关键码(key)的值而直接进行访问的数据结构。

一般哈希表都是用来快速判断一个元素是否出现集合里。如果使用枚举法的话,时间复杂度为O(n),而使用哈希表的话则只需要O(1)。

哈希函数通过hashCode把名字转化为数值,一般hashcode是通过特定编码方式,可以将其他数据格式转化为不同的数值,这样就把学生名字映射为哈希表上的索引数字了。

代码随想录算法训练营Day6|哈希表理论基础、242.有效的字母异位词、349.两个数组的交集、202.快乐数、1.两数之和_第1张图片

哈希碰撞:如果需要取哈希数的值的总数量大于哈希表的长度,就会导致几个数据被映射到哈希表同一个索引下标的位置。那么可以使用两种办法,一种是拉链法,即出现碰撞的部位使用链表按序排放;一种是线性探测法,这种方法要求哈希表全长较大,就是向下寻找空位放入数据。

js当中一般使用map而不使用set。

使用哈希表是一种牺牲空间换时间的做法。

二、242 有效的字母异位词

  1. 题目链接:https://leetcode.cn/problems/valid-anagram/

  1. 思路:为两个字符串分别构造长度为26的数组,用每个字符的ascii码顺序来当作键,每次加一,最后比较两个数组。时间复杂度为O(n)

  1. 代码:

var isAnagram = function(s, t) {
    // 记住fill这个方法
    var sMap = new Array(26).fill(0);
    var tMap = new Array(26).fill(0);
    var a = 'a';
    for (let i=0; i

  1. 383 赎金信

题目链接:https://leetcode.cn/problems/ransom-note/

思路:和上题几乎一样,可以用26位数组也可以用map。这里展示的代码用的是map。

代码:

var canConstruct = function(ransomNote, magazine) {
    var array = magazine.split('');
    var map = new Map();
    for (let i=0; i

  1. 49 字母异位词分组

题目链接:https://leetcode.cn/problems/group-anagrams/

思路:将每个词产生的26位数组作为object的key,而将这个词本身添加进value的列表当中。最后返回这个object的所有value。为什么不用map?因为map的键不可以是数组。哈希表的实现是基于地址的,两个所有元素相等但地址不同的数组是不一样的,不会在一个map的键下面。

代码:

var groupAnagrams = function(strs) {
    const map = new Object();
    for (let s of strs) {
        const count = new Array(26).fill(0);
        for (let c of s) {
            count[c.charCodeAt() - 'a'.charCodeAt()]++;
        }
        map[count] ? map[count].push(s) : map[count] = [s];
    }
    return Object.values(map);
};

也可以用排序后的字符串当作键。

  1. 438 找到字符串中所有字母异位词

题目链接:https://leetcode.cn/problems/find-all-anagrams-in-a-string/

思路:将初始的字典找出,然后利用滑动窗口解题。

三、349 两个数组的交集

  1. 题目链接:https://leetcode.cn/problems/intersection-of-two-arrays/

  1. 思路:创建一个数组的map,再用另一个数组与之比较

  1. 代码:

var intersection = function(nums1, nums2) {
    var result = [];
    var map = new Map();
    for (let i=0; i

  1. 350 两个数组的交集II

题目链接:https://leetcode.cn/problems/intersection-of-two-arrays-ii/

思路:与349其实很像,但是这一次不能找到了就将map中对应的值删掉,而是每次减一,直到不能减了再删掉,这样才能让共同出现的次数与其实际情况相同。

代码:

var intersect = function(nums1, nums2) {
    var result = [];
    var map = new Map();
    for (let i=0; i

四、202 快乐数

  1. 题目链接:https://leetcode.cn/problems/happy-number/

  1. 思路:用一个history数组记录下目前所有得出的数据,只要曾经出现重复就返回false,出现1就返回true

  1. 代码:

var isHappy = function(n) {
    var history = [];
    var number = n;
    while (true) {
        var array = number.toString().split('');
        var result = 0;
        for (let i=0; i

五、1 两数之和

  1. 题目链接:https://leetcode.cn/problems/two-sum/

  1. 思路:依次遍历数组,既然只有一组符合答案的数据,那么可以每次经过的时候都判断是否有target-当前值的这样一个数据存在在map中,如果有的话就返回,没有的话在map中加入[value: key]键值对。

  1. 代码:

var twoSum = function(nums, target) {
    var map = new Map();
    for (let i=0; i

今日学习时长:2h左右

总结:今天438题脑袋转不动先不写了,总体还可以,对map的掌握熟练了一些,下次刷的时候需重点注意438和49。今天学到了map的键不可以是数组,因此有时需要合理使用toString()函数,而且记住fill函数, var array = new Array(26).fill(0)。

你可能感兴趣的:(算法训练营,javascript,数据结构,算法,哈希表)