zoukankan      html  css  js  c++  java
  • (本周总结)工具库源码+算法+原生

    202快乐数

    对于一个正整数,每一次将该数替换为它每个位置上的数字的平方和,然后重复这个过程直到这个数变为 1

    如果可以变为1,那么这个数就是快乐数

    输入: 19
    输出: true
    解释:
    12 + 92 = 82
    82 + 22 = 68
    62 + 82 = 100
    12 + 02 + 02 = 1
    
    /*和不等于1,且重复就不是快乐树*/
    const isHappy = n => {
        let set = new Set()
        n += ''
        let sum = 0
        while (sum != 1) {
            sum = 0
            for (let i = 0; i < n.length; i++) {
                sum += n[i] ** 2
            }
            if (set.has(sum)) return false
            n=sum+''
            set.add(sum)
        }
        return true
    }
    console.log(isHappy(20))//false
    
    //第二种
    const isHappy = n => {
        let exit = []
        let sum
        while (n != 1) {
            sum = 0
            while (n !=0) {
                sum += (n % 10) ** 2
                n = parseInt(String(n / 10))
            }
            if (exit.indexOf(sum) > -1) {
                return false
            }else{
                exit.push(sum)
            }
            n=sum
        }
        return true
    
    }
    

    Leetcode 1137 第 N 个泰波那契数

    输入:n = 4
    输出:4
    T0 = 0, T1 = 1, T2 = 1, 且在 n >= 0 的条件下 Tn+3 = Tn + Tn+1 + Tn+2
    
    给你整数 n,请返回第 n 个泰波那契数 Tn 的值。
    T_3 = 0 + 1 + 1 = 2
    T_4 = 1 + 1 + 2 = 4
    
    const Solution = n => {
      const arr = [0, 1, 1]
      if (n < 3) {
        return arr[n]
      }
      return Solution(n - 3) + Solution(n - 2) + Solution(n - 1)
    }
    console.log(Solution(5))
    
    const Solution = n => {
      const arr = [0, 1, 1]
      if (n < 3) {
        return arr[n]
      }
      for (let i = 3; i <= n; i++) {
        arr[i] = arr[i - 3] + arr[i - 2] + arr[i - 1]
      }
      return arr[n]
    }
    console.log(Solution(5))
    

    LeetCode 179 数组拼接为最大数

    输入: [10,2]
    输出: 210
    
    输入: [3,30,34,5,9]
    输出: 9534330
    
    const largesNumber = nums => {
      nums = nums.map(String)
      nums.sort((a, b) => parseInt(b + a) - parseInt(a + b))
      if(nums[0]==0) return '0'
      return nums.join('')
    }
    

    LeetCode 200

    const numIslands = nums => {
      if (nums.length == 0) return 0;
      let count = 0;
      for (let i = 0; i < nums.length; i++) {
        for (let j = 0; j < nums[0].length; j++) {
          if (nums[i][j] == 1) {
            count++
            helper(i, j, nums)
          }
        }
      }
      return count
    }
    const helper = (i, j, nums) => {
      if (i < 0 || j < 0 || i >= nums.length || j >= nums[0].length || nums[i][j] != 1) return ;
      nums[i][j] = '*';
      helper(i - 1, j, nums);
      helper(i + 1, j, nums);
      helper(i, j - 1, nums);
      helper(i, j + 1, nums)
    }
    console.log(numIslands([['1', '0', '1', '1', '1'], ['1', '0', '1', '0', '1'], ['1', '1', '1', '0', '1']]))
    

    198 打家劫舍

    相邻两家不能同时闯入

    输入: [1,2,3,1]
    输出: 4
     1 + 3 = 4 
     
    输入: [2,7,9,3,1]
    输出: 12
     2 + 9 + 1 = 12 
    
    const rob1 = nums => {
      let a = 0,
        b = 0;
      for (let i = 0; i < nums.length; i++) {
        if (i % 2 == 0) {
          //a += nums[i];
         // a = Math.max(b, a)
          a = Math.max(b, (a + nums[i]))
        } else {
          // b+=nums[i]
          // b=Math.max(a,b) 
          b = Math.max(a, (b + nums[i]))
        }
      }
      return Math.max(a, b)
    }
    
    ///动态规划
    
      let n = nums.length;
      if (n <= 1) return n == 0 ? 0 : nums[0];
      let arr = [];
      arr[0] = nums[0];
      arr[1] = nums[1]
      for (let i = 2; i < n; i++) {
        arr[i] = Math.max(arr[i - 1], nums[i] + arr[i - 2]);
      }
      console.log(arr)
      return arr[n - 1]
    }
    
    

    leetCode 191 位1的个数

    const hammingh = n => n.toString(2)
      .split('')
      .reduce((acc, val) => (val == '1' && acc++, acc), 0)
    

    leetCode 190 颠倒二进制位

    var reverseBits = n => {
      let t = n.toString(2).split('')
      while (t.length < 32) {
        t.unshift('0')
      }
      return parseInt(t.reverse().join(''),2)
    };
    
    console.log(reverseBits(100))
    

    leetCode 49

    输入: ['abc','acb','bbc','cbb']

    输出: [['abc','acb'],['bbc','cbb']]

    const GroupAnrgrams = strs => {
      let map = new Map();
      for (let i = 0; i < strs.length; i++) {
        let key=strs[i].split('').sort().join();
        if (!map.has(key)) {
          map.set(key,[strs[i]])
        }else{
          let temp=map.get(key)
          temp.push(strs[i])
          map.set(key,temp)
        }
      }
      return Array.from(map.values())
    }
    console.log(GroupAnrgrams(['abc', 'bcd', 'mss','bca']))
    

    leetCode 5 最长回文子串

    输入: "babad"

    输出: "bab"

    const Solution = str => {
      let n = str.length;
      let res = ''
      const helper = (i, j) => {
        //查找回文的中心
        while (i >= 0 && j < n && str[i] == str[j]) {
          i -= 1
          j += 1
        }
        //确定好边界
        if (res.length < j - i - 1) {
          res = str.slice(i + 1, j)
        }
      }
      for (let i = 0; i < n; i++) {
        helper(i,i)
        helper(i,i+1)
      }
      return res
    }
    console.log(Solution('abcbaddd'))
    
    
    //第二种
    //这种for循环看得少
    for (let i = 0; i < n; i++) {
        for (let j = i; j >= 0; j--) {}}
    n=3
    //输出的结果
    [ [ 0, 0 ],
      [ 1, 1 ],
      [ 1, 0 ],
      [ 2, 2 ],
      [ 2, 1 ],
      [ 2, 0 ],
      [ 3, 3 ],
      [ 3, 2 ],
      [ 3, 1 ],
      [ 3, 0 ] ]
    不好理解,我就不写啦
    

    164. 最大间距

    给定一个无序的数组,找出数组在排序之后,相邻元素之间最大的差值。

    例如

    输入: [3,6,9,1]

    输出: 3

    const maxinum = nums => {
      let n = nums.length;
      let res = 0;
      if (n < 2) {
        return 0
      }
      nums.sort((a,b)=>a-b)
      for (let i = 1; i < n; i++) {
        res = Math.max(res, nums[i] - nums[i - 1])
      }
      return res
    }
    

    DOM复习

    document.querySelector 返回第一个匹配的Element

    document.querySelectorAll 返回的是一个类数组

    Array.from(document.querySelectorAll('.aaa'))
      .forEach(val => val.innerHTML = '333');
       [...document.querySelectorAll('.aaa')].map(val=>val.innerHTML='333')
    

    但是上面的这两种性能较差,尽量使用

    document.getElementById()
    document.getElementsByTagName()
    

    属性查找

     document.querySelector("div[class='bbb']")
    

    后代查找

    $el.querySelector('.bbb')
    

    兄弟元素

     let a=document.querySelector('.bbb')
          //我的父节点的所有孩子,除掉自身的所有兄弟节点
         let b=[...a.parentNode.children].filter(val=>val!==a)
    

    上一个元素

    el.previousElementSibling;
    

    下一个元素

    el.nextElementSibling;
    

    Input/Textarea

    document.querySelector('.aaa').value
    

    event

    在vue中是在点击或者其实事件传入$event
    原生事件委托
     let a=document.querySelector('.aaa')
    a.addEventListener('click',(e)=>{
            console.log(e.target) //拿到点击的dom节点
          })
    

    获取属性

    el.getAttribute('class')
    

    设置属性

    el.setAttribute('属性','值')
    

    添加class

    $el.classList.add('aaaa')
    

    删除class

    $el.classList.remove('aaa')
    

    has class

    $el.classList.contains('aaa')
    

    toggle class

    $el.classList.toggle('aaa')
    

    offset 偏移

    offsetWidth和offsetHight 获取节点的宽度和高度

    offset宽/高  =  盒子自身的宽/高 + padding+border;
    `offsetWidth` =width+padding+border;
    `offsetHeight` =Height+padding+border;
    

    offsetLeft和offsetTop (检测距离父盒子有定位的左/上面的距离)

    offsetParent (检测父系盒子中带有定位的父盒子节点)

    区别

    offsetTop返回的是只读的,且返回的是数字

    scroll

    scrollTop
    scrollLeft
    

    Rambda工具库源码学习

    curry() 这个很经典放前面

    curry((a,b,c)=>a+b+c)(1,2,3) //6
    curry((a,b,c)=>a+b+c)(1)(2)(3) //6
    
    const curry = (fn, args = []) =>
      (..._args) => (rest => rest.length >= fn.length ? fn(...rest) : curry(fn, rest))([...args, ..._args])
    
    const curry = (fn, ...args) =>
      fn.length <= args.length ? fn(...args) : curry.bind(null, fn, ...args);
    
    好懂版
    const curry = (fn, ...args) => (..._args) => (test => test.length < fn.length ? curry(fn, ...test) : fn(...test))([...args, ..._args])
    
    const curry = (fn, ...args) => {
      if (args.length<fn.length) {
        return curry.bind(null, fn, ...args)
      }
      return fn(...args)
    }
    

    add()

    add(1,2) //3
    add(1)(2) //3
    
    function add(a, b) {
      if (arguments.length == 1) {
        return _=>add(a,_)
      }
      return a+b;
    }
    

    adjust()

    adjust(val=>val+1,1,[1,2,3])// [1,3,3]
    const adjustRaw = (fn, idx, list) => {
      const clone = list.slice()
      const Index = list.length > 0 ? idx : list.length - idx;
      clone[Index] = fn(clone[Index])
      return clone
    }
    

    all()

    all(v => v > -1, [1, 1, 1, 1, -1])// false
    all(val=>val==2)([2, 2, 2, 2,]) //true
    
    function all(fn, list) {
      if (arguments.length == 1) return _ => all(fn, _)
      return list.every(fn)
    }
    

    allPass

    const input = {
      a: 1,
      b: 2,
    }
    const rules = [
      x => x.a === 1,
      x => x.b === 2,
    ]
    allPass(rules, input) //true
    allPass(rules)(input)//true
    
    function allPass(fnArray, obj) {
      if (arguments.length == 1) return _ => allPass(fnArray, _);
      return fnArray.some(fn => fn(obj))
    }
    

    always

    const always = val => () => val
    always(3)() //3
    

    defaultTo

    如果第二个参数不是 nullundefinedNaN

    则返回第二个参数,否则返回第一个参数(默认值)

    defaultTo(300)(undefined/null/NaN)  //300
    defaultTo(300)(30) //30
    defaultTo(300,undefined,null,3) //30
    
    const flag = s => s == undefined || Object.is(s, NaN)
    
    function defaultTo(a, ...b) {
      if (arguments.length == 1) {
        return _ => defaultTo(a, _)
      }
      if (arguments.length == 2) {
        return flag(b[0]) ? a : b[0]
      }
      let i = 0;
      while (i < b.length) {
        if (!flag(b[i])) {
          return b[i]
        }
        i++
      }
      return a
    }
    

    dissoc()

    dissoc('b', {a: 1, b: 2, c: 3}); //=> {a: 1, c: 3}
    
    function dissoc(prop, obj) {
      if (arguments.length == 1) {
        return _ => dissoc(prop, _)
      }
      if (obj == undefined || obj == null) {
        return {}
      }
      let a = Object.assign({}, obj)
      delete a[prop]
      return a
    }
    

    equals

    const type = val => {
      if (typeof val == 'number') {
        return isNaN(val) ? 'NaN' : 'number'
      } else {
        return Object.prototype.toString.call(val)
          .split(' ')[1].slice(0, -1)
      }
    }
    
    function equals(a, b) {
      if (arguments.length == 1) {
        return _ => equals(a, _)
      }
      if (a === b) {
        return true
      }
      if (type(a) !== type(b)) {
        return false
      }
      if (type(a) == 'Array') {
        let aArray = a.concat()
        let bArray = b.concat()
        if (aArray.toString() !== bArray.toString()) {
          return false
        }
        let flag = true;
        aArray.forEach((val, index) => {
          if (flag) {
            if (val != bArray[index] && !equals(val, bArray[index])) {
              flag = false
            }
          }
        })
        return flag;
      }
      if (type(a) == 'Object') {
        const aKeys = Object.keys(a)
        if (aKeys.length !== Object.keys(b).length) {
          return false
        }
        let flag = true;
        aKeys.map(val => {
          if (flag) {
            const aValue = a[val];
            const bValue = b[val];
            if (aValue !== bValue && !equals(aValue, bValue)) {
              flag = false
            }
          }
        })
        return flag
      }  
      return false
    }
    

    lodash源码深入

    after()

    调用多少次后才执行

    const after = (n, func) => {
      return (...args) => {
        if (--n < 1) {
          return func.apply(null, args)
        }
      }
    }
    
    **例子**
    let f = after(2, (a, b) => {
      return a + b
    })
    console.log(f(2, 3)) //undefined
    console.log(f(2, 3))  //5   
    

    before(n,func)

    调用不超过n次

    const before = (n, func) => {
      return (...args) => {
        if (n-- > 0) {
          return func.apply(null, args)
        }
          func=undefined
      }
    }
    let a=before(2,(a,b)=>a+b)
    console.log(a(1, 2)) //3
    console.log(a(1, 2)) //3
    console.log(a(1, 2)) //undefined
    

    sum(array)

    const sums = array => {
      let result = 0;
      if (array != null && array.length) {
        for (let item of array) {
          result += item
        }
      }
      return result
    }
    

    pull(array,...args)

    **例子**
    let myArray = ['a', 'b', 'c', 'a', 'b', 'c'];
    pull(myArray, 'a', 'c'); // myArray = [ 'b', 'b' ]   
    
    const pull = (arr, ...args) => {
      let pulled = arr.filter(val => !args.includes(val))
      //删除原有数组的元素
      arr.length = 0
      pulled.forEach(val => arr.push(val))
    };
    let arr = [1, 2, 3, 4, 5]
    pull(arr, 1, 2)
    console.log(arr)
    

    uuid(a,b)

    UUID 是 通用唯一识别码

    function uuid(a, b) {
      for (
        b = a = ''; a++ < 36;
        b += a * 51 & 52 ?
          (a ^ 15 ? 8 ^ Math.random() * (a ^ 20 ? 16 : 4) : 4).toString(16)
          : '-') ;
      return b
    }
    console.log(uuid(2, 3))
    //4f656637-ea34-4a16-a4b0-31872ab177da
    
    这种位运算我这种级别还看不懂,先写上去
    

    deepClone()

    const deepClone = obj => {
      let clone = Object.assign({}, obj)
      Object.keys(clone)
        .forEach(val => {
          clone[val] = typeof obj[val] == 'object' ? deepClone(obj[val]) : obj[val]
        })
      if (Array.isArray(obj) && obj.length) {
        return (clone.length = obj.length) && Array.from(clone)
      } else {
        return Array.isArray(obj) ? Array.from(obj) : clone
      }
    }
    
    

    mb()

    //要查找的对象
    var obj1 = {
      a: {
        b: [{ hello: 'world' }]
      }
    };
    //要查找的条件
    const arr = ['a', 'b', 0, 'hello']
    console.log(a(arr)(obj1))
    //world
    const mb=p=>obj=>p.map(val=>obj=(obj||{})[val])&&obj
    

    qart

    给二维码添加背景

    自执行函数

    void function() {
      console.log(0)
    }()
    +function(){
      console.log(1)
    }()
    -function(){
      console.log(2)
    }()
    ~function(){
      console.log(3)
    }();
    !function(){
      console.log(4)
    }();
    (function(){
      console.log(5)
    })()
    

    对象成员

    const obj={
      name:'zhangsan',
      age:12,
      method(){
          return 2
      }  
    }
    for (let item in obj) {
      console.log(item)  //打印键
    }
    
    使用对象成员的`.`  `[]`
    "." 和"[]" 都是对象成员存取运算符,所不同的是:
    前面右边的运算元必须是一个标识符,后面中间的运算元可以是变量,直接量或表达式
    obj.name
    obj['name']
    
    obj.method()
    obj.['method']()
    
  • 相关阅读:
    Javascript 闭包
    纯CSS实现侧边栏/分栏高度自动相等
    css实现16:9的图片比例
    CSS实现宽高成比例缩放
    div等比例缩放-------纯CSS实现自适应浏览器宽度的正方形
    websocket 实现简单网页版wechat
    Flask 简单使用,这一篇就够了!
    图灵机器人 V1 和 V2 接入方法
    Django中的cookie和session
    django 三件套(render,redirect,HttpResponse)
  • 原文地址:https://www.cnblogs.com/fangdongdemao/p/11328648.html
Copyright © 2011-2022 走看看