代码随想录第五天

前言

哈希相对链表,感觉理解起来比较容易,今天比较顺利,已经可以独立做出来了,而且可以写出多种解法,继续加油!

242.有效的字母异位词

解题思路
给定两个字符串 s 和 t ,编写一个函数来判断 t 是否是 s 的字母异位词。

注意:若 s 和 t 中每个字符出现的次数都相同,则称 s 和 t 互为字母异位词。

示例 1:

输入: s = “anagram”, t = “nagaram”
输出: true
示例 2:

输入: s = “rat”, t = “car”
输出: false

提示:

1 <= s.length, t.length <= 5 * 104
s 和 t 仅包含小写字母

暴力解法

先转成数组,然后排序,然后比较两个字符串是否相等,简单粗暴

var isAnagram = function(s, t) {
if(s.length!==t.length) return false
     if([...s].sort().join('')!==[...t].sort().join(''))return false
     return true
     }

哈希表解法

使用ASCII码做映射,然后看数组最终的值是否为0。非常巧妙的一个方法

var isAnagram = function(s, t) {
 const arr=new Array(26).fill(0);//定义一个长26的值全部为0的数组
    for(let i=0;i<s.length;i++){
        arr[s.charCodeAt(i)-'a'.charCodeAt(0)]++ //s.charCodeAt(i)-'a'.charCodeAt(0) 为数组arr的下标,因为初始化都是0,++之后就会大于0
    }
    for(let i=0;i<t.length;i++){
        arr[t.charCodeAt(i)-'a'.charCodeAt(0)]--
        if(arr[t.charCodeAt(i)-'a'.charCodeAt(0)]<0) return false //如果 -- 之后出现小于0的情况,就说明t中出现了s中没有的字母,直接返回false
    }
    return true
}

map方法

var isAnagram = function(s, t) {
 if(s.length !== t.length) return false;
    let char_count = new Map();//定义一个map
    for(let item of s) {
      char_count.set(item, (char_count.get(item) || 0) + 1) ; //使用setset,给item赋值,由于初始化的map为空,get(item)肯定为undefind,给0.然后+1
    }
    for(let item of t) {
      if(!char_count.get(item)) return false;//如果出现了map中没有的item。或者get(item)==-1,直接返回false
      char_count.set(item, char_count.get(item)-1);
    }
    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] 也是可通过的

提示:

1 <= nums1.length, nums2.length <= 1000
0 <= nums1[i], nums2[i] <= 1000

map+set

var intersection = function(nums1, nums2) {
  const arr=new Set()
    const arr1=new Map();
    for(const i in nums1){
        arr1.set(nums1[i],i)
    }
    for(const i in nums2){
        if(arr1.get(nums2[i])){
            arr.add(nums2[i])
        }
    }
  
    return [...arr]
};

set

var intersection = function(nums1, nums2) {
   // 根据数组大小交换操作的数组
    if(nums1.length < nums2.length) {
        const _ = nums1;
        nums1 = nums2;
        nums2 = _;
    }
    const nums1Set = new Set(nums1);
    const resSet = new Set();
    // for(const n of nums2) {
    //     nums1Set.has(n) && resSet.add(n);
    // }
    // 循环 比 迭代器快
    for(let i = nums2.length - 1; i >= 0; i--) {
        nums1Set.has(nums2[i]) && resSet.add(nums2[i]);
    }
    return [...resSet];
};

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

提示:

1 <= n <= 231 - 1

map

var isHappy = function (n) {
    let m = new Map()

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

    while (true) {
        // n出现过,证明已陷入无限循环
        if (m.has(n)) return false
        if (n === 1) return true
        m.set(n, 1)
        n = getSum(n)
    }
}

set

var getSum = function (n) {

   
    let sum = 0;
    while (n) {
        sum += (n % 10) ** 2;
        n =  Math.floor(n/10);
    }
    return sum;
}
var isHappy = function(n) {
    let set = new Set();   // Set() 里的数是惟一的
    // 如果在循环中某个值重复出现,说明此时陷入死循环,也就说明这个值不是快乐数
    while (n !== 1 && !set.has(n)) {
        set.add(n);
        n = getSum(n);
    }
    return n === 1;
};

1. 两数之和

解题思路
作为leetcode的开门题,之前就做过,用的是最简单粗暴的双循环。这次了解了哈希之后,才看了卡哥的两行文字解释,就直接明白怎么写了。
给定一个整数数组 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]

提示:

2 <= nums.length <= 104
-109 <= nums[i] <= 109
-109 <= target <= 109
只会存在一个有效答案

暴力破解

var twoSum = function(nums, target) {
    let fast = 1
    let slow = 0
    while(slow<nums.length){
        for(let i=fast;i<nums.length;i++){
            if(nums[slow]+nums[i]===target){
                return [slow,i]
            }
        }
        fast++
        slow++
    }

 }

map

var twoSum = function(nums, target) {

//版本一
    const temp = new Map();
    for(let i = 0;i<nums.length;i++){
        temp.set(nums[i],i)
    }
    for(let i = 0;i<nums.length;i++){
        if(temp.get(target-nums[i])&&temp.get(target-nums[i])!==i){ //map中存在key为target-nums[i]的时候,判断value不等于 i 去掉本身相加
            return [i,temp.get(target-nums[i])]
        }
    }

//版本二
// 少写一个for循环
     const map = new Map();
        for(let i = 0, len = nums.length; i < len; i++){
            if(map.has(target - nums[i])){
                return [map.get(target - nums[i]), i];
            }else{
                map.set(nums[i], i);
            }
        }
};
 }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值