LeetCode | 242.有效的字母异位词
题目:
给定两个字符串 s 和 t ,编写一个函数来判断 t 是否是 s 的字母异位词。
注意:若 s 和 t 中每个字符出现的次数都相同,则称 s 和 t 互为字母异位词。
242.有效的字母异位词https://leetcode.cn/problems/valid-anagram/
思考:
- 之前对哈希表不够了解,所以花了点时间去了解哈希表;
- 自己思考的时候是想要将两个字符串的字符都取出来,然后进行比较,后面发现不可信;
- 看了视频讲解后觉得很妙,细节看题解的备注;
题解:
var isAnagram = function(s, t) {
// 判断两个字符串的长度是否相同
if(s.length !== t.length) return false
// 创建一个长度为26的数组,代表着26个字母在字符串中出现的个数
const resArray = new Array(26).fill(0)
// 遍历取出数组中的每个数,与字母的第一位a相减
const base = "a".charCodeAt()
for(let i of s){
let j = i.charCodeAt() - base
// 数组相应位置的数加1
resArray[j]++
}
// 另一个字符串同理
for(let i of t){
let j = i.charCodeAt() - base
// 数组的相应位置减1
resArray[j]--
}
// 遍历resArray数组,如果里面的元素都为0,那么就可以说明……
for(let i = 0; i < resArray.length; i++){
if(resArray[i] !== 0){
return false
}
}
return true
};
LeetCode | 349.两个数组的交集
题目:给定两个数组nums1和nums2,返回它们的交集。输出结果中的每个元素一定是唯一的。我们可以不考虑输出结果的顺序 。
349.两个数组的交集https://leetcode.cn/problems/intersection-of-two-arrays/
思考:
- 看了一点提示,知道这道题需要用set(因为之前的题目是没有规定数组长度的大小的,但是后面规定了数组的长小于等于1000,所以是可以用数组直接解,并且用数组反而会更快);
题解:
var intersection = function (nums1, nums2) {
// 先将两个数组转化为set去重
nums1 = new Set(nums1)
nums2 = new Set(nums2)
// 创建一个新的Set
let nums3 = new Set()
// 迭代
for (const item of nums1) {
if (nums2.has(item)) {
nums3.add(item)
}
}
// 返回3
return Array.from(nums3)
};
-----------------------------------下面是参考答案-----------------------------------------
var intersection = function(nums1, nums2) {
// 根据数组大小交换操作的数组(我的题解因为偷懒没有判断哪个数组更大,所以如果操作到更长的数组的话,会迭代很久,是一个bug,需要注意!!!!不过这里因为规定了数组的上限,所以看似没有问题了。)
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 Array.from(resSet);
};
LeetCode | 202.快乐数
题目:
编写一个算法来判断一个数 n 是不是快乐数。
「快乐数」 定义为:
对于一个正整数,每一次将该数替换为它每个位置上的数字的平方和。
然后重复这个过程直到这个数变为 1,也可能是 无限循环 但始终变不到 1。
如果这个过程 结果为 1,那么这个数就是快乐数。
如果 n 是 快乐数 就返回 true ;不是,则返回 false 。
202.快乐数https://leetcode.cn/problems/happy-number/
思考:
- 看了一点提示后自己写出来的,是一道信心题,就像提示说的那样,只要知道怎么将数字取平方并相加,其他的就很简单了;
- 将数字取平方并相加后,发现题目说的很明显,只有两种结果:sum无限循环或者是等于1,所以要判断一个元素是否出现集合里的时候,就要考虑哈希法,而set里面是不会有重复元素的,所以用set
题解:
var isHappy = function (n) {
// 思路:先将n的每个位上的数字进行平方相加操作→将得到的sum添加进一个set中→一直这样做直到sum=1或者set中出现了重复的数
let sum = 0;
let num = n + '';
let reSet = new Set();
while (sum !== 1) {
sum = 0;
for (let i = 0; i < num.length; i++) {
sum += num[i] * num[i]
}
if (!reSet.has(sum)) {
reSet.add(sum)
num = sum + ''
} else {
return false
}
}
return true
};
LeetCode | 1.两数之和
题目:
给定一个整数数组 nums 和一个整数目标值 target,请你在该数组中找出和为目标值target的那两个整数,并返回它们的数组下标。
你可以假设每种输入只会对应一个答案。但是,数组中同一个元素在答案里不能重复出现。
你可以按任意顺序返回答案。
1.两数之和https://leetcode.cn/problems/two-sum/
思考:
- 提示说需要使用map,不过我掌握的不够熟悉,虽然用了map,但是暴力解法(hhhhh),第一次看到执行用时288ms的;
- 看了题解过后觉得思想很妙,双层for循环是为了取出来相加,但是知道和、一个加数,另一个加数是可以通过减法减出来的!!好思想!
- 并且题解都没有new Map(),直接是创建的一个空对象,只能说理解map理解得很深刻,不像我只会用这些方法……
题解:
var twoSum = function (nums, target) {
// 创建一个map
var newMap = new Map()
// 遍历数组
for(var i = 0; i < nums.length; i++){
// 判断newMap中是否有与nums[i]相加为target的key
if(newMap.get(target - nums[i]) !== undefined){
return [i, newMap.get(target - nums[i])]
}
// 不符合的话,就将其加入newMap
newMap.set(nums[i], i)
}
return[]
};
-----------------------------------下面是参考答案-----------------------------------------
var twoSum = function (nums, target) {
let hash = {};
for (let i = 0; i < nums.length; i++) { // 遍历当前元素,并在map中寻找是否有匹配的key
if (hash[target - nums[i]] !== undefined) {
return [i, hash[target - nums[i]]];
}
hash[nums[i]] = i; // 如果没找到匹配对,就把访问过的元素和下标加入到map中
}
return [];
};
哈希表思路总结:
- 当我们需要查询一个元素是否出现过,或者一个元素是否在集合里的时候,就要第一时间想到哈希法;
- 根据需要处理的数据,选择合适的结构:数组、map、set;
- 数组的大小受限制,而且如果元素很少,而哈希值太大会造成内存空间的浪费(如果题目没有限制数组的大小,那么考虑用其他的来完成哈希表的题目);
- set是一个集合,里面放的元素只能是一个key,set中元素不能重复(set把数值映射到key上都要做hash计算,所以set不仅占用空间比数组大,而且速度要比数组慢);
map是一种key value的存储结构,可以用key保存数值,用value在保存数值所在的下标;