242.有效的字母异位词
文章链接
第一想法
题目要求需要判断两个字符串中各个字母出现的次数是否相同。所以想到了map,set无法判断出现的此时,所以用map,代码如下:
function isAnagram(s: string, t: string): boolean {
let map=new Map()
if(s.length!=t.length) return false //如果长度不同直接返回false
for(let i=0;i<s.length;i++){ //存储第一个字符串
if(map.has(s[i])){
map.set(s[i],map.get(s[i])+1)
}else{
map.set(s[i],1)
}
}
for(let i=0;i<t.length;i++){
if(!map.has(t[i])) return false //map中没有t[i],则返回false
let num=map.get(t[i])
num-=1
if(num<0) return false
map.set(t[i],num)
}
return true
};
看完文章后的想法
很简单,感觉用牛刀斩小鸡,直接用数组就行了,话不多说,上代码!
function isAnagram(s: string, t: string): boolean {
let arr:number[]=new Array(26).fill(0)
for(let i=0;i<s.length;i++){
arr[s[i].charCodeAt(0)-'a'.charCodeAt(0)]++
}
for(let i=0;i<t.length;i++){
arr[t[i].charCodeAt(0)-'a'.charCodeAt(0)]--
}
if(arr.every(item=>item==0)) return true
return false
};
思考
接触哈希表后,一定要分清什么情况用什么,这道题用数组就行,我用了map,也能做出来,但是感觉有点浪费了。推荐代码随想录中的哈希表的基础讲解,看完后一定有不同的感触
349. 两个数组的交集
文章链接
第一想法
这道题由例子可知,即使相同的数字重复多次输出结果也只为一次,所以一定时间想到了用set,代码如下:
function intersection(nums1: number[], nums2: number[]): number[] {
let set=new Set()
let res=new Set()
for(let i=0;i<nums1.length;i++){
set.add(nums1[i])
}
for(let i=0;i<nums2.length;i++){
if(set.has(nums2[i])) res.add(nums2[i])
}
return Array.from(res) as number[]
};
看完文章后的想法
看完之后,才发现我对set的方法以及使用不是很了解,可以直接通过new Set(数组)来直接创建set,不用我上面写的代码的第一个for循环,代码如下:
function intersection(nums1: number[], nums2: number[]): number[] {
let set=new Set(nums1) //第一个for循环由这个代码就可以解决
let res=new Set()
for(let i=0;i<nums2.length;i++){
if(set.has(nums2[i])) res.add(nums2[i])
}
return Array.from(res) as number[]
};
还有一种骚操作,这里很考验对js方法的理解程度,上代码:
function intersection(nums1: number[], nums2: number[]): number[] {
//先通过filter查找两个数组相同的元素,通过new Set去重,最后在转变为数组
return Array.from(new Set(nums1.filter(item=>nums2.includes(item))))
};
思考
对于骚操作的写法确实牛逼,同时也让我明白了要多理解set,map以及数组。同时要熟悉这些方法,这样代码才能写好。推荐在MDN中看set,map的方法以及一些使用.这道题不太难。
202. 快乐数
文章推荐
第一想法
文章有个很重要的限制条件,我感觉没有这个限制条件的话可能不就是easy题了,题目说明了根据规则要不就是无限循环,要不就是最终等于1,所以知道了无限循环,就知道一个判断条件,如果他之前出现过,就肯定不是快乐数,判断一个数是否出现,所以用set,代码如下:
function isHappy(n: number): boolean {
let set=new Set()
let num=n+''
while(true){//进行循环判断
if(set.has(num)) return false //如果是循环出现,则一定不是快乐数,返回false
set.add(num)//存储每一步得到的结果
if(num=="1") return true
let n=0
for(let i=0;i<num.length;i++){
n+=(num[i] as any as number)**2
}
num=n+""
}
}
看完文章后的想法
总体想法和自己刚开始的想法是一样的,就是代码写法不太一样,代码如下:
function isHappy(n: number): boolean {
let set=new Set()
let num=n+""
const foo=(num:string)=>{
let n=0
for(let i=0;i<num.length;i++){
n+=(num[i] as any as number)**2
}
return n+""
}
while(num!="1"&&!set.has(num)){
set.add(num)
num=foo(num)
}
return num=="1"
};
思考
这道题也是不难的,只要把题目中的无限循环搞清楚就可以了。如果把无限循环这个条件去掉,则难度绝不会是easy了。
1. 两数之和
文章链接
第一想法
第一想到的数组,因为数组有个indexOf的方法,所以尝试了一下:
function twoSum(nums: number[], target: number): number[] {
for(let i=0;i<nums.length;i++){
let index=nums.lastIndexOf(target-nums[i])//这里用lastIndexOf是防止nums=[3,3],target=6这种情况时,返回[0,0]的情况
if(index!=-1&&index!=i) return [i,index]
}
};
发现能通过,完美!一看结果,再一看消耗时间,好家伙,252 ms,忒慢了。决定看文章
看完文章后的想法
没想到,确实没想到,可以用map,而且我之前的写法用了for和lastIndexOf(),时间复杂度应该挺高的,不说了直接上代码:
function twoSum(nums: number[], target: number): number[] {
let map=new Map()
for(let i=0;i<nums.length;i++){
if(map.has(target-nums[i])) return [map.get(target-nums[i]),i]
map.set(nums[i],i)
}
};
代码思路是在for循环中寻找是否有等于target-nums[i]的数字,循环过的变量就用map存储起来,方便查找。
思考
这道题不难,对于要频繁查询的题要首先想到用哈希表来计算,这道题就是没想到这层含义,有点可惜。
今日总结
代码时间2.30个小时,今天比较忙,就不写那么多了。