技术要点:
1、存储唯一值的数据结构、是以键值对的形式来储存
2、ES6中有字典、名为map
3、键值对增删改查
(1)map的增删改查
let map = new Map();
// 增
map.set('a', 'aa');
map.set('b', 'bb');
// 删
map.delete('b');
// map.clear();
// 改
map.set('a', 'aaa');
console.log('map', map)
console.log('get', map.get('a'))
console.log('has', map.has('a'))
console.log('size', map.size)
(2)leetcode: 349 : 两个数组的交集
// 求两个数的交集
// 以其中一个数组创建字典、然后在另外一个数组中判断哪些值在字典里面有
function diff (n1,n2) {
const map = new Map()
n1.forEach(item => {
map.set(item, true)
});
const res = []
n2.forEach(item => {
if(map.get(item)) {
res.push(item)
map.delete(item) // 已经了就删除,避免重复push相同的值
}
})
return res}
(3) leetCode: 20题目, 检测有效的字符串括号是否都是闭合。(字典、 栈)
// 有效的括号
// 建立一个栈【】、碰到左括号就是入栈,碰到右括号类型匹配就出栈,
// 建立有规定的字典
// 类型不匹配判断不合法
// 最后栈空了就合法,否则不合法,
// 最佳优化:基数肯定不合法
function validate (s) {
if(s.length %2 === 1) return false
let stack = []
let map = new Map()
map.set('(',')')
map.set('{','}')
map.set('[',']')
for(let i = 0; i< s.length; i++) {
let cur = s[i]
if(map.has(cur)) {
stack.push(cur)
} else {
const last = stack[stack.length - 1] // 拿出栈里面的最后一个做判断
if(map.get(last) === cur) {
stack.pop()
} else {
return false
}
}
}
return stack.length === 0
}
validate('(){}[]')
(4)两数值和: leetcode 1
// 建立字典,进行匹配动作类似婚姻介绍所找对象。寻找自己的目标,先把自己的信息存入字典
// 根据目标值,后续有符合的新对象过来就会自动去查找是否符合
// 给定目标值: 建立两个数字求和的匹配对象字典
// 用时间换空间的解法:最佳优化方式: 后续
function sum (n1,n2) {
const map = new Map()
for(let i = 0; i<n1.length; i++) {
const cur = n1[i]
const target = n2-cur
if(map.has(target)) {
return [i, map.get(target)]
} else {
map.set(cur,i)
}
}}
console.log(sum([2,7,11,15], 9))
(5)leetCode 3 : 无重复字符的最长子串 和 对应值
// 无重复字符的*最长*子串*
// 注意子串而
// 子序列: 字符窜串中存在的值
// 子串:字符窜必须是完整的剪切
// 难点: 双子针移动、建立滑动窗口,用来剪切子串
// 不断移动右指针、遇到重复字符、就把左指针移动到重复字符的下一位
// 过程中、记录所有窗口长度、并返回最大值
// n1左指针、i右指针、m最大长度值
function length (str) {
let n1 = 0
let m = 0
let res = []
let map = new Map()
for(let i=0; i<str.length; i++) {
const cur = str[i]
if(map.has(cur) && map.get(cur) >= 1) {
n1 = map.get(cur) + 1
}
m = Math.max(m, i-n1 +1) // 获取最大长度
map.set(cur, i)
}
for(let key of map.keys()) {
res.push(key)
}
if(res.length === m) {
return {
[m]: res
}
} else {
return {
[m]: res.slice(-m)
}
}}
console.log(length('abbcdea'))
(6) vue 利用闭包构造map缓存数据
vue中判断我们写的组件名是不是html内置标签的时候,如果用数组类遍历那么将要循环很多次获取结果,如果把数组转为对象,把标签名设置为对象的key,那么不用依次遍历查找,只需要查找一次就能获取结果,提高了查找效率。
function makeMap (str, expectsLowerCase) {
// 构建闭包集合map
var map = Object.create(null);
var list = str.split(',');
for (var i = 0; i < list.length; i++) {
map[list[i]] = true;
}
return expectsLowerCase
? function (val) { return map[val.toLowerCase()]; }
: function (val) { return map[val];
}}
// 利用闭包,每次判断是否是内置标签只需调用isHTMLTag
var isHTMLTag = makeMap('html,body,base,head,link,meta,style,title')
console.log('res', isHTMLTag('body')) // true