一、 理论
1. 字典简介
- 与集合类似,字典也是一种存储唯一值的数据结构,是以 键值对 的形式存储的
- es6中有字典Map
1.1 增
const m = new Map()
m.set('a', 'aa')
m.set('b', 'bb')
1.2 删
m.delete('b')
m.clear()
1.3 改
m.set('a', 'aaa')
1.4 查
m.get('a')
二、刷题
1. 两个数组的交集(349)
1.1 题目描述
- 给定两个数组,编写一个函数来计算它们的交集
- 说明
- 输出结果中的每个元素一定是唯一的
- 我们可以不考虑输出结果的顺序
1.2 解题思路
输入:nums1 = [1,2,2,1], nums2 = [2,2]
输出:[2]
- 用字典建立一个映射关系,记录nums1里有的值
- 遍历nums2,找出nums1中有的值
1.3 解题步骤
- 新建一个字典,遍历nums1,填充字典
- 遍历nums2,遇到字典里有的值就选出并从字典中删除
function intersection(nums1, nums2) {
const map = new Map()
nums1.forEach(item => map.set(item, true))
const res = []
nums2.forEach(item => {
if(map.has(item)) {
res.push(item)
map.delete(item)
}
})
return res
}
1.4 时间复杂度&空间复杂度
- 时间复杂度:O(n+m)
- 空间复杂度:O(n)
2. 有效的括号(20)
2.1 题目描述
- 给定一个只包括 '(',')','{','}','[',']' 的字符串 s ,判断字符串是否有效
- 有效字符串需满足:
- 左括号必须用相同类型的右括号闭合
- 左括号必须以正确的顺序闭合
2.2 解题思路
输入:s = "()"
输出:true
2.3 解题步骤
function isValid(s) {
if(s.length % 2 == 1) return false
const stack = []
const map = new Map()
map.set('(', ')')
map.set('{', '}')
map.set('[', ']')
for(let i = 0; i < s.length; i++) {
let c = s[i]
if(map.has(c)) {
stack.push(c)
} else {
const t = stack[stack.length-1]
if(map.get(t) === c) {
stack.pop()
} else {
return false
}
}
}
return stack.length == 0
}
2.4 时间复杂度&空间复杂度
- 时间复杂度:O(n)
- 空间复杂度:O(1)
3. 两数之和(1)
3.1 题目描述
- 给定一个整数数组 nums 和一个整数目标值 target,请你在该数组中找出 和为目标值 target 的那 两个 整数,并返回它们的数组下标
- 你可以假设每种输入只会对应一个答案。但是,数组中同一个元素在答案里不能重复出现
- 你可以按任意顺序返回答案
3.2 解题思路
输入:nums = [2,7,11,15], target = 9
输出:[0,1]
- nums相亲者 target匹配条件
- 用字典建立婚姻介绍所,存储相亲者的数字和下标
3.3 解题步骤
- 新建字典作为婚姻介绍所
- 遍历nums写入字典
function twoSum(s) {
const map = new Map()
for(let i = 0; i < nums.length; i++) {
const n = nums[i]
const n2 = target - n
if(map.has(n2)) {
return [map.get(n2), i]
}
map.set(n, i)
}
}
3.4 时间复杂度&空间复杂度
- 时间复杂度:O(n)
- 空间复杂度:O(n)
4. 无重复字符的最长子串(3)
4.1 题目描述
- 给定一个字符串 s ,请你找出其中不含有重复字符的 最长子串 的长度
4.2 解题思路
输入:s = "abcabcbb"
输出:3
- 先找出所有不包含重复字符的子串
- 找出最长的子串,返回其长度
4.3 解题步骤
- 双指针维护滑动窗口
- 不断移动右指针,遇到重复字符,就把左指针移动到重复字符的下一位
- 移动过程中记录所有窗口的长度并返回最大值
function lengthOfLongestSubstring(s) {
let l = 0
let res = 0
const map = new Map()
for(let r = 0; r < s.length; r++) {
if(map.has(s[r]) && map.get(s[r] >= l)) {
l = map.get(s[r])+1
}
res = Math.max(res, r - l + 1)
map.set(s[r], r)
}
}
4.4 时间复杂度&空间复杂度
- 时间复杂度:O(n)
- 空间复杂度:O(m)
5. 最小覆盖子串(76)
5.1 题目描述
- 给你一个字符串 s 、一个字符串 t
- 返回 s 中涵盖 t 所有字符的最小子串
- 如果 s 中不存在涵盖 t 所有字符的子串,则返回空字符串 ""
- 注意
- 对于 t 中重复字符,我们寻找的子字符串中该字符数量必须不少于 t 中该字符数量
- 如果 s 中存在这样的子串,我们保证它是唯一的答案
5.2 解题思路
输入:s = "ADOBECODEBANC", t = "ABC"
输出:"BANC"
- 先找出所有包含t的子串
- 找出最长的子串,返回其长度
5.3 解题步骤
- 双指针维护滑动窗口
- 不断移动右指针,找到包含t的子串,移动左指针,尽量减少包含t的子串的长度
function minWindow(s, t) {
let l = 0, r = 0
const need = new Map()
for(let c of t) {
need.set(c, need.has(c) ? need.get(c)+1 : 1)
}
let needType = need.size
let res = ''
while(r < s.length) {
const c = s[r]
if(need.get(c)) {
need.set(c, need.get(c)-1)
if(need.get(c) == 0) needType--
}
while(needType == 0) {
const newRes = s.substring(l, r+1)
if(!res || newRes.length < res.length) res = newRes
const c2 = s[l]
if(need.has(c2)) {
need.set(c2, need.get(c2)+1)
if(need.get(c2) == 1) needType++
}
l++
}
r++
}
}
5.4 时间复杂度&空间复杂度
- 时间复杂度:O(m+n)
- 空间复杂度:O(m)
三、总结 -- 技术要点
- 与集合类似,字典也是一种存储唯一值的数据结构,是以 键值对 的形式存储的
- es6中有字典Map
- 字典常用操作:键值对的增删改查