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

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

今天手hash专场。
什么时候想到用哈希法,当我们遇到了要快速判断一个元素是否出现集合里的时候,就要考虑哈希法。
当我们想使用哈希法来解决问题的时候,我们一般会选择如下三种数据结构:
数组
set (集合)
map(映射)

242.有效的字母异位词

leetcode-242.有效的字母异位词 ------简单

题目描述 && 测试案例

给定两个字符串 s 和 t ,编写一个函数来判断 t 是否是 s 的字母异位词。
注意:若 s 和 t 中每个字符出现的次数都相同,则称 s 和 t 互为字母异位词。
示例 1:
输入: s = “anagram”, t = “nagaram”
输出: true
示例 2:
输入: s = “rat”, t = “car”
输出: false

解题思路 && 解题代码

var isAnagram = function(s, t) {
    //首先考虑不符合的情况,如果s和t的长度不相等。自然就不是异位词了。
    if(s.length !== t.length) return false
    //本道的核心就是看t的字母是不是在s中出现,也就是判断一个字符是否出现在s中,想到hash结构
    //使用哪种结构?
    //选择数组比较合适,26个字符长度固定为26,以0填充,出现了就在相应的位置+1,不涉及map的set等。
    const arr1 = new Array(26).fill(0)
    //遍历s字符串利用charcodeat得到码 在减去‘a’的,就得到了对应的0-25
    for(let i = 0; i < s.length; i++) {
        //遍历进行++
        arr1[s[i].charCodeAt() - 'a'.charCodeAt()]++
    }
    //再次遍历t,进行--
    for(let j = 0; j < t.length; j++) {
        arr1[t[j].charCodeAt() - 'a'.charCodeAt()]--;
        //如果减了之后变成负数就说明不相等,不相等的话就不是有效的,返回false
        if(arr1[t[j].charCodeAt() - 'a'.charCodeAt()] < 0) {
            return false
        }
    }
    return true;
};

349.两个数组的交集

题目描述 && 测试案例

给定两个数组 nums1 和 nums2 ,返回 它们的交集 。输出结果中的每个元素一定是 唯一 的。我们可以 不考虑输出结果的顺序 。

示例 1:
输入:nums1 = [1,2,2,1], nums2 = [2,2]
输出:[2]
示例 2:
输入:nums1 = [4,9,5], nums2 = [9,4,9,8,4]
输出:[9,4]
解释:[4,9] 也是可通过的

解题思路 && 解题代码

集合论中,设A,B是两个集合,由所有属于集合A且属于集合B的元素所组成的集合,叫做集合A与集合B的交集(intersection),记作A∩B。
上一题使用了hash结构中的数组,但是如果哈希值比较少、特别分散、跨度非常大,使用数组就造成空间的极大浪费。上一道题 hash值就是26个,所以使用数组是合适的,但这道题数组就不合适了,会造成浪费。
题目说每个结果是唯一的,三种结构中能做到唯一的就是set了,并且使用set进行去重,也降低了复杂度。

js中let…of与let…in
for in:(它大部分用于遍历数组的索引(key值))
定义:用于循环遍历数组或对象属性,fot in循环里面的index是string类型的,代码每执行一次,就会对数组的元素或者对象的属性进行一次操作
缺点:某些情况下,会出现随机顺序的遍历,因为里面的值是string类型,所以增加了转换过程,因此开销较大
优点:可以遍历数组的键名,遍历对象简洁方便

for of:(可遍历map,object,array,set string等)用来遍历数据,比如数组中的元素s值,
优点:避免了for in的所有缺点,可以使用break,continue和return,不仅支持数组的遍历,还可以遍历类似数组的对象,支持字符串的遍历
最简洁,最直接的遍历数组的语法,支持map和Set对象遍历
缺点:不适用于处理原有的原生对象(原生对象是一个子集,包含一些在运动过程中动态创建的对象)

var intersection = function(nums1, nums2) {
    //使用set对两个数组先去重
    let set1 = new Set(nums1)
    let set2 = new Set(nums2)
    let res = [];
    for(let n1 of set1) {
        if(set2.has(n1)){
            res.push(n1)
        }
    }
    return res
};

202. 快乐数

leetcode-202.快乐数

题目描述 && 测试案例

编写一个算法来判断一个数 n 是不是快乐数。
「快乐数」 定义为:
对于一个正整数,每一次将该数替换为它每个位置上的数字的平方和。
然后重复这个过程直到这个数变为 1,也可能是 无限循环 但始终变不到 1。
如果这个过程 结果为 1,那么这个数就是快乐数。
如果 n 是 快乐数 就返回 true ;不是,则返回 false 。

示例 1:
输入:n = 19
输出:true
解释:
12 + 92 = 82
82 + 22 = 68
62 + 82 = 100
12 + 02 + 02 = 1

示例 2:
输入:n = 2
输出:false

解题思路 && 解题代码

var isHappy = function(n) {
    //本道题的核心就是看有没有重复循环,有重复循环就false,重复的话就会想到set
    let set = new Set();
    //进行一个循环,什么时候循环?n!=1的时候,说明还不是快乐数
    while(n != 1) {
        //写一个得到下一个n的方法
        n = getNext(n)
        //如果下一个n在set里面肯定就返回false了
        if(set.has(n)){
            return false
        }
        set.add(n)
    }
    return n===1
};
//如何得到下一个n
var getNext = function(n) {
    let sum = 0
    while(n > 0){
        sum = sum + Math.pow(n % 10, 2)
        n = Math.floor(n / 10)
    }
    return sum
};

1. 两数之和

题目描述 && 测试案例

给定一个整数数组 nums 和一个整数目标值 target,请你在该数组中找出 和为目标值 target 的那 两个 整数,并返回它们的数组下标。
你可以假设每种输入只会对应一个答案。但是,数组中同一个元素在答案里不能重复出现。
你可以按任意顺序返回答案。

示例 1:
输入:nums = [2,7,11,15], target = 9
输出:[0,1]
解释:因为 nums[0] + nums[1] == 9 ,返回 [0, 1] 。

示例 2:
输入:nums = [3,2,4], target = 6
输出:[1,2]

示例 3:
输入:nums = [3,3], target = 6
输出:[0,1]

解题思路 && 解题代码

思路一:果然。。。。暴力大法好,不放代码了。
思路二:

var twoSum = function(nums, target) {
    // 为什么会想到用哈希表?
    //本道题的本质其实还是看一个元素target是否出现在一个数组里面

    // 哈希表为什么用map
    //数组的话,会造成浪费,set有去重功能,明显不太合适,所以选择map

    // 本题map是用来存什么的
    //map来存放我们遍历过的元素,然后在遍历数组的时候去询问这个集合,某元素是否遍历过,也就是是否出现在这个集合。

    // map中的key和value用来存什么的
    //key存mums[i] value存对应是索引值。

    //创建一个hash表
    let hash = {};
    //遍历数组nums
    for(let i = 0; i < nums.length; i++) {
        //如果targettarget- nums[i] !== undefined 就说明存在
        if(hash[target - nums[i]] !== undefined) {
            //returnreturn 下标
             return [i, hash[target - nums[i]]];
        }
        //如果不存在,就添加到hash中
        hash[nums[i]] = i;
    }
    //没有 返回空[]
    return [];
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值