算法字典(map)

144 阅读2分钟

技术要点:

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