基础随想
hash表构造的三种方式
数组,map,set
(有空再写)
有效字母异位
leetcode 242
给定两个字符串 s 和 t ,编写一个函数来判断 t 是否是 s 的字母异位词。
注意:若 s 和 t 中每个字符出现的次数都相同,则称 s 和 t 互为字母异位词。
输入: s = “anagram”, t = “nagaram”
输出: true
var isAnagram = function(s, t) {
if(s.length != t.length) return false
// 创建一个字典存储,这里用数组
const resSet = new Array(26).fill(0)
// 定义a的基准
const base = "a".charCodeAt()
for(const i of s){
// 让s中的字母在对应的索引位置上值加1
resSet[i.charCodeAt()-base]++
}
for(const i of t){
// 判断逻辑:如果t字符串寻到一个为0的位置,意味着t中出现了某个新的字母,直接return false
if(!resSet[i.charCodeAt()-base]) return false
resSet[i.charCodeAt()-base]--
}
return true
};
tips
charCodeAt() 方法可返回指定位置的字符的 Unicode 编码,返回值是 0 - 65535 之间的整数,表示给定索引处的 UTF-16 代码单元。
字符串中第一个字符的位置为 0, 第二个字符位置为 1,以此类推。
相关题目
leetcode383
给你两个字符串:ransomNote 和 magazine ,判断 ransomNote 能不能由 magazine 里面的字符构成。
输入:ransomNote = “aa”, magazine = “ab”
输出:false
输入:ransomNote = “aa”, magazine = “aab”
输出:true
var canConstruct = function(ransomNote, magazine) {
const resSet = new Array(26).fill(0)
const base = "a".charCodeAt()
// 表直接用26个,ransom先加,magazine后减(m还要长),减到负数无所谓,后面按0判断
for(const i of ransomNote){
resSet[i.charCodeAt() - base]++
}
for(const i of magazine){
resSet[i.charCodeAt() - base]--
}
for(let i=0;i<resSet.length;i++){
if(resSet[i]>0){
return false
}
}
return true
};
leetcode 49
给你一个字符串数组,请你将 字母异位词 组合在一起。可以按任意顺序返回结果列表。
字母异位词 是由重新排列源单词的字母得到的一个新单词,所有源单词中的字母通常恰好只用一次
输入: strs = [“eat”, “tea”, “tan”, “ate”, “nat”, “bat”]
输出: [[“bat”],[“nat”,“tan”],[“ate”,“eat”,“tea”]]
var groupAnagrams = function(strs) {
let res = []
let map = new Map()
for(let i=0;i<strs.length;i++){
// 输入数组中的每个单词,进行单独拆分
let k = strs[i].split('').sort().join('')
// 如果为实例1,则i=0时,k=aet
if(map.has(k)){
map.get(k).push(strs[i])
}else{
map.set(k,[strs[i]])
}
}
map.forEach((val,key)=>{
res.push(val)
})
return res
};
tips
打印一下map
arr = ["the","been","eben","eebn","tah"]
Map(3) {'eht' => Array(1), 'been' => Array(3), 'aht' => Array(1)}
[[Entries]]
0: {"eht" => Array(1)}
key: "eht"
value: ['the']
1: {"been" => Array(3)}
key: "been"
value: (3) ['been', 'eben', 'eebn']
2: {"aht" => Array(1)}
key: "aht"
value: ['ath']
size: 3
[[Prototype]]: Map
leetcode 438
给定两个字符串 s 和 p,找到 s 中所有 p 的 异位词 的子串,返回这些子串的起始索引。不考虑答案输出的顺序。
输入: s = “cbaebabacd”, p = “abc”
输出: [0,6]
解释:
起始索引等于 0 的子串是 “cba”, 它是 “abc” 的异位词。
起始索引等于 6 的子串是 “bac”, 它是 “abc” 的异位词。
var findAnagrams = function (s, p) {
const pLen = p.length
const res = [] // 返回值
const map = new Map() // 存储 p 的字符
for (let item of p) {
map.set(item, map.get(item) ? map.get(item) + 1 : 1)
}
// 存储窗口里的字符情况
const window = new Map()
let valid = 0 // 有效字符个数
for (let i = 0; i < s.length; i++) {
const right = s[i]
// 向右扩展
window.set(right, window.get(right) ? window.get(right) + 1 : 1)
// 扩展的节点值是否满足有效字符
if (window.get(right) === map.get(right)) {
valid++
}
if (i >= pLen) {
// 移动窗口 -- 超出之后,收缩回来, 这是 pLen 长度的固定窗口
const left = s[i - pLen]
// 原本是匹配的,现在移出去了,肯定就不匹配了
if (window.get(left) === map.get(left)) {
valid--
}
window.set(left, window.get(left) - 1)
}
// 如果有效字符数量和存储 p 的map 的数量一致,则当前窗口的首字符保存起来
if (valid === map.size) {
res.push(i - pLen+1)
}
}
return res
};
// 别人的答案,我没写
两个数组的交集
leetcode349
输入:nums1 = [1,2,2,1], nums2 = [2,2]
输出:[2]
var intersection = function(nums1, nums2) {
// let set = new Set(nums2)
// return [...new Set(nums1)].filter((val)=>set.has(val))
let nums1Set = new Set(nums1)
let res = []
for(let i=0;i<nums2.length; i++){
let temp = nums2[i]
if(nums1Set.has(temp)){
res.push(temp)
}
}
res = new Set(res)
// Array.from 转换成数组
return Array.from(res)
};
leetcode350
const res = []
nums2.forEach((item) => {
const index = nums1.indexOf(item)
if (index !== -1){
res.push(item);
nums1[index] = null;
}
})
return res;
快乐数
leetcode202
难点,个人认为是怎么给那个表达式搞出来
var getSum = function(n){
let sum = 0
while(n){
sum = sum + (n % 10) ** 2
n = Math.floor(n/10)
}
return sum
}
var isHappy = function(n) {
let set = new Set()
while(n != 1 && !set.has(n) ){
set.add(n)
n = getSum(n)
}
return n == 1
};
两数之和
leetcode1
let map = new Map()
for(let i=0; i<nums.length; i++){
let otherNum = target - nums[i]
if(map.has(otherNum)){
return [map.get(otherNum),i]
}
map.set(nums[i],i)
}
四数相加
leetcode454
给你四个整数数组 nums1、nums2、nums3 和 nums4 ,数组长度都是 n ,请你计算有多少个元组 (i, j, k, l) 能满足:
输入:nums1 = [1,2], nums2 = [-2,-1], nums3 = [-1,2], nums4 = [0,2]
输出:2
解释:
两个元组如下:
(0, 0, 0, 1) -> nums1[0] + nums2[0] + nums3[0] + nums4[1] = 1 + (-2) + (-1) + 2 = 0
(1, 1, 0, 0) -> nums1[1] + nums2[1] + nums3[0] + nums4[0] = 2 + (-1) + (-1) + 0 = 0
var fourSumCount = function(nums1, nums2, nums3, nums4) {
let map = new Map()
let n = nums1.length
let sum1 = 0, sum2 = 0, valid = 0, search = 0
for(let i=0; i<n; i++){
for(let j=0; j<n; j++){
sum1 = nums1[i] + nums2[j]
map.set(sum1, map.has(sum1) ? map.get(sum1)+1 : 1)
}
}
for(let i=0; i<n; i++){
for(let j=0; j<n; j++){
sum2 = nums3[i] + nums4[j]
search = -sum2
if(map.has(search)){
valid = map.get(search) + valid // 不是自增1,想清楚
}
}
}
return valid
};
tips
视频里面讲的非常清楚了,数组1和2循环相加然后存字典,3和4加去字典里面找,为数不多看一半视频,写出来改一次过的
课程来自代码随想录