• 2021年flag-300+道算法~~~


      面对薄弱的算法,在此定一个flag,2021年实现300道+算法题,以此记录  时间2021-01-01 23:36:55开始

    递归相关练习

      1、commentId  为空代表一级 不为空会等于上一条的_id 实现树状结构  代码如下

    /**
     * @description 
     * @author cq
     * @Date 2021-01-01 22:48:23
     * @LastEditTime 2021-01-01 23:39:05
     * @LastEditors cq
     */
    
    //  commentId 代表一级   不为空会等于上一条的_id
    // 怎么 按照 h1 h2 h3的这种层级顺序渲染出来
    const arr = [
      {
        commentId: "98bb04175fef248a00f405f81c80d217",
        createTime: "2021-01-01 13:33:55",
        questionId: "a8831daa5fec73020126af6b2940f269",
        text: "回复1-1的1-1-2",
        user_id: "o2ml-5c_nKI2Tf9pLBJBCdnbu5v4",
        _id: "85ff8afa5fef24c401285c05361e3a60",
      },
      {
        commentId: "98bb04175fef248a00f405f81c80d217",
        createTime: "2021-01-01 13:33:35",
        questionId: "a8831daa5fec73020126af6b2940f269",
        text: "回复1-1的1-1-1",
        user_id: "o2ml-5c_nKI2Tf9pLBJBCdnbu5v4",
        _id: "2424fa985fef24af0106b8f77f917199",
      },
      {
        commentId: "2f6ab8515fef247600ebabef520933ce",
        createTime: "2021-01-01 13:33:13",
        questionId: "a8831daa5fec73020126af6b2940f269",
        text: "回复第三条3-1",
        user_id: "o2ml-5c_nKI2Tf9pLBJBCdnbu5v4",
        _id: "9f2a34705fef2499012c075e4669fe44",
      },
      {
        commentId: "2f6ab8515fef246400ebab0350bf130a",
        createTime: "2021-01-01 13:32:58",
        questionId: "a8831daa5fec73020126af6b2940f269",
        text: "回复第一条1-1",
        user_id: "o2ml-5c_nKI2Tf9pLBJBCdnbu5v4",
        _id: "98bb04175fef248a00f405f81c80d217",
      },
      {
        commentId: "",
        createTime: "2021-01-01 13:32:38",
        questionId: "a8831daa5fec73020126af6b2940f269",
        text: "我是第三条",
        user_id: "o2ml-5c_nKI2Tf9pLBJBCdnbu5v4",
        _id: "2f6ab8515fef247600ebabef520933ce",
      },
      {
        commentId: "",
        createTime: "2021-01-01 13:32:30",
        questionId: "a8831daa5fec73020126af6b2940f269",
        text: "我是第二条评论",
        user_id: "o2ml-5c_nKI2Tf9pLBJBCdnbu5v4",
        _id: "98bb04175fef246e00f4046a439f441b",
      },
      {
        commentId: "",
        createTime: "2021-01-01 13:32:20",
        questionId: "a8831daa5fec73020126af6b2940f269",
        text: "我是第一条评论",
        user_id: "o2ml-5c_nKI2Tf9pLBJBCdnbu5v4",
        _id: "2f6ab8515fef246400ebab0350bf130a",
      },
    ]
    
    
    function deep(array = [], commentId = "", newArr = []) {
      let arr = array.filter(item => item.commentId == commentId);
      for (let index = 0; index < arr.length; index++) {
        const element = arr[index];
        newArr.push({
          item: element,
          children: []
        }); //第一次把第一条评论放进来
        const downObj = array.find(item => item.commentId == newArr[newArr.length - 1].item._id);
        if (downObj) {
          deep(array, element._id, newArr[index].children)
        } else {
          continue
        }
      }
      return newArr
    }
    console.log(deep(arr, "", []), "deep")
    View Code

      2、实现数字的阶乘

    /**
     * @description
     * @author cq
     * @Date 2021-01-03 19:59:32
     * @LastEditTime 2021-01-03 20:03:17
     * @LastEditors cq
     */
    
    /*
        使用递归 求n的阶乘
        假设 写好了一个函数 factorial
        1:1
        2:1*2  ->fn(1)*2
        3:1*2*3 ->fn(2)*3
        4:1*2*3*4 ->fn(3)*4
        ...
        n:1*2*3...*n ->factorial(n-1)*n
    */
    
    const factorial=(n)=>{
      // 条件是
      if (n == 1) {
        return 1;
      }
      return factorial(n - 1) * n;
    }
    
    console.log(factorial(2));
    console.log(factorial(3));
    console.log(factorial(4));
    console.log(factorial(100));
    View Code

        3、求两个数的最大公约数

    /**
     * @description 求两个数最大公约数
     * @author cq
     * @Date 2021-01-05 17:26:05
     * @LastEditTime 2021-01-05 17:51:42
     * @LastEditors cq
     */
    
    /*
    例:48, 57
    57 % 48=9     大数对小数求余
    48 % 9=3       小数对上次的余数求余,重复这个过程直到余数为0
    
    9 % 3=0         余数为0时,此次求余的小数就是最大公约数 
    */
    
    //功能:求两个数的最大公约数 //参数:两个数: //返回值:最大公约数
    
    // max 是大数 min 是小数
    const commonDivisor = (min, max) => {
    
      if (max % min) {
        return commonDivisor(max % min, min)
      } else {
        return min
      }
    }
    
    console.log(commonDivisor(9, 12))
    console.log(commonDivisor(4, 2))
    console.log(commonDivisor(49, 7))
    console.log(commonDivisor(16, 12))
    View Code

        4、求前一百的和

    /**
     * @description 求和
     * @author cq
     * @Date 2021-01-05 19:52:33
     * @LastEditTime 2021-01-05 20:14:41
     * @LastEditors cq
     */
    
    // 求前一百的和
    
    const add=(num)=>{
      if(num==1){
        return 1
      }
      return add(num - 1) + num
    }
    
    console.log(add(100));
    View Code

        5、青蛙跳问题

    /**
     * @description 青蛙跳
     * @author cq
     * @Date 2021-01-08 16:03:23
     * @LastEditTime 2021-01-08 16:34:54
     * @LastEditors cq
     */
    
    // 一只青蛙一次可以跳上1级台阶,也可以跳上2级。
    // 求该青蛙跳上一个n级的台阶总共有多少种跳法(先后次序不同算不同的结果)。
    
    // 1-1
    // 4-5
    
    // 1 - 1 - 1 - 1
    // 2 - 2
    // 1 - 2 - 1
    // 1 - 1 - 2
    // 2 - 1 - 1
    let reccord = {};
    function jumpFloor(number) {
      // 开局要么先跳1要么2
      if (number === 1) {
        return 1
      }
      if (number === 2) {
        return 2
      }
      console.log(reccord, "reccord");
      if (reccord[number]) {   //最小肯定是3开始计数
        return reccord[number]
      }
      let res = jumpFloor(number - 1) + jumpFloor(number - 2);
      console.log(res, "res", reccord);
      reccord[number] = res
      console.log(reccord, "--");
      return res
    }
    
    console.log(jumpFloor(5));
    View Code

    数组相关练习

      6、求任意两数之和在数组中查找

    /**
     * @description 求任意数组中的两项之和
     * @author cq
     * @Date 2021-01-08 16:40:32
     * @LastEditTime 2021-01-08 17:35:01
     * @LastEditors cq
     */
    
    /*
      给出一个整数数组,请在数组中找出两个加起来等于目标值的数,
      你给出的函数twoSum 需要返回这两个数字的下标(index1,index2),需要满足 index1 小于index2.。注意:下标是从1开始的
      假设给出的数组中只存在唯一解
      例如:
      给出的数组为 [20, 70, 110, 150] , 目标值为90
      输出 index1 = 1, index2 = 2 
    */
    
    
    // 79ms
    const twoSum1 = (numbers, target) => {
      for (let index = 0; index < numbers.length; index++) {
        const element = numbers[index];
        let findIndex = numbers.findIndex((item, i) => item === (target - element) && i != index);  //循环太多余
        if (findIndex != -1) {
          return [index + 1, findIndex + 1]
        }
      }
    }
    
    // 46ms
    const twoSum = (numbers, target) => {
      const map = new Map();
      for (let i = 0; i < numbers.length; i++) {
        console.log("进来几次", numbers[i]);
        // 初始话的map肯定是个空的
        // 第二次进来的就不是3了  而是第二次循环的2  所以对比之下就能排除了我们写的那个排除自身的逻辑了
        if (map.has(target - numbers[i])) {
          return [map.get(target - numbers[i]) + 1, i + 1]
        } else {
          // 第一次将3放进去 和他的下标i
          map.set(numbers[i], i)
        }
      }
    }
    
    
    console.log(twoSum([3, 2, 4], 6));  //[2,3]
    // console.log(twoSum([0, 4, 3, 0], 0));  //[ 1, 4 ]
    View Code

      7、数组的奇偶性分离

    /**
     * @description 数组奇偶性分离
     * @author cq
     * @Date 2021-01-08 17:40:46
     * @LastEditTime 2021-01-11 10:18:59
     * @LastEditors cq
     */
    
    
    /*
      输入一个整数数组,实现一个函数来调整该数组中数字的顺序,
      使得所有的奇数位于数组的前半部分,所有的偶数位于数组的后半部分,
      并保证奇数和奇数,偶数和偶数之间的相对位置不变。
     */
    
    function reOrderArray(array) {
      let arr1=[]
      let arr2=[]
      for (let index = 0; index < array.length; index++) {
        const element = array[index];
        if (element%2){
          // 奇数
          arr1.push(element)
        }else{
          arr2.push(element)
        }
      }
      return [...arr1,...arr2]
    }
    
    console.log(reOrderArray([1,2,3,4,5,6,7,9,8])); 
    View Code

      8、加起来的值为目标值的组合

    /**
     * @description 加起来的值为目标值的组合
     * @author cq
     * @Date 2021-01-11 10:39:34
     * @LastEditTime 2021-01-11 14:56:15
     * @LastEditors cq
     */
    
    // function duplicate(array) {
    //   let arr = []
    //   for (let index = 0; index < array.length; index++) {
    //     const element = array[index];
    //     arr.push(element.sort().join(","))
    //   }
    //   return [...new Set(arr)]
    // }
    
    // function deep(num, target, arr) {
    //   for (let index = 0; index < num.length; index++) {
    //     const element = num[index];
    //     // 第一次循环把直接两数相加等于目标值的数找出来
    //     const i = num.indexOf(target - element);
    //     if (i != -1) {
    //       arr.push([element, num[i]]);
    //     } else {
    //       return deep(num, target - element)
    //     }
    //   }
    //   return arr
    // }
    
    
    // function combinationSum2(num, target) {
    //   let arr=[];
    //   for (let index = 0; index < num.length; index++) {
    //     const element = num[index];
    //     // 第一次循环把直接两数相加等于目标值的数找出来
    //     const i = num.indexOf(target - element);
    //     if (i!=-1){
    //       arr.push([element, num[i]]);
    //     }else{
    //       deep(num, target - element, arr)
    //     }
    //   }
    //   return duplicate(arr).map(item=>item.split(","))
    // }
    
    function combinationSum2(num, target) {
      num.sort((a, b) => a - b);
      let res = [];  //最终结果
      let temp = [];
      find(num, 0, target, temp, res);
      return res;
    }
    function find(num, start, target, temp, res) {
      // 当目标值减到0了就终止整个递归
      if (target == 0) {
        res.push([...temp]);
        return;
      }
      // target >= num[i] 如果目标值不如当前值大了就没有意思了
      for (let i = start; i < num.length && target >= num[i]; i++) {
        // 当下标大于0的时候且上一项与当前项相等的时候直接跳过
        console.log(i, start,"i, start");
        if (i > start && num[i] == num[i - 1]) {
          continue;
        }
        temp.push(num[i]);  //依次push 10-10-20-50  不合适-50 (10-10-20)再进去此时start保留在了3 不合适-20 再往后 加60合适
        console.log(temp, "temp-start");
        find(num, i + 1, target - num[i], temp, res);
        console.log(temp,"temp");
        temp.pop();
        console.log(temp, "pop");
      }
    }
    
    // [100,10,20,70,60,10,50],80
    console.log(combinationSum2([100, 10, 20, 70, 60, 10, 50], 80));
    // 返回 [[10,10,60],[10,20,50],[10,70],[20,60]]
    View Code

        9、数组中相加和为0的三元组

    /**
     * @description 数组中相加和为0的三元组
     * @author cq
     * @Date 2021-01-11 15:07:04
     * @LastEditTime 2021-01-11 16:20:25
     * @LastEditors cq
     */
    
    function threeSum(num) {
      let temp = [];
      let res = [];
      num.sort((a, b) => a - b);
      find(num, 0, temp, res);
      return res
      function find(num, start, temp, res) {
        if (temp.length == 3) {
          const [a, b, c] = temp;
          if (a + b + c == 0) {
            res.push([...temp])
            return
          }
        }
        for (let index = start; index < num.length; index++) {
          const element = num[index];
          // 主要目的就是去重
          if (index > start && element == num[index - 1]) {
            continue
          }
          temp.push(element)
          find(num, index + 1, temp, res)
          temp.pop()
        }
      }
    }
    
    function threeSum1(num) {
      // write code here
      num.sort((a, b) => a - b)
      let res = [], len = num.length
      for (let i = 0; i < len - 2; i++) {
        let j = i + 1, k = len - 1
        // k , j 分别表示尾部开始的最后一项和当前想的下一项
        if (i == 0 || num[i] != num[i - 1]) {
          while (k > j) {
            if (num[i] + num[j] + num[k] == 0) {
              // 满足条件 直接放进
              res.push([num[i], num[j], num[k]])
              // 头部去重(如果后面一个数跟当前的数字相等,则代表有重复的结果生成,跳过)
              while (j + 1 < k && num[j + 1] === num[j]) j++;
              // 尾部去重(如果前面一个数跟当前的数字相等,则代表有重复的结果生成,跳过)
              while (k - 1 > j && num[k - 1] === num[k]) k--;
    
              k--;
              j++
            } else if (num[i] + num[j] + num[k] > 0) {
              // 因为当前数组是按照从小到大排序的  所以如果三项大于0 肯定越往后越大于0
              // 反之一样
              k--
            } else if (num[i] + num[j] + num[k] < 0) {
              j++
            }
          }
        }
      }
      return res
    }
    
    console.log(threeSum([-2, 0, 1, 1, 2, -3, -4, 3, 4,-3,3]), "threeSum");  //[[-2,0,2],[-2,1,1]]
    console.log(threeSum1([-2, 0, 1, 1, 2, -3, -4, 3, 4,-3,3]), "threeSum1");  //[[-2,0,2],[-2,1,1]]
    View Code

      10、数组中未出现的最小正整数

    /**
     * @description 数组中未出现的最小正整数
     * @author cq
     * @Date 2021-01-11 16:40:05
     * @LastEditTime 2021-01-11 17:08:54
     * @LastEditors cq
     */
    
    
    /*
      给定一个无序数组arr,找到数组中未出现的最小正整数
      例如arr = [-1, 2, 3, 4]。返回1
      arr = [1, 2, 3, 4]。返回5
      [要求]
      时间复杂度为O(n)O(n),空间复杂度为O(1)O(1)
    */
    
    // 废柴 错误
    function minNumberdisappered(arr) {
      arr.sort((a, b) => a - b);
      let i = 0
      while (i < arr.length) {
        if (arr[i] >= 0) {
          // 从大于0的时候开始计算
          if ((arr[i] + 1) != arr[i + 1]) {
            return arr[i] + 1
          }
        } else {
          if (arr[i + 1] > 0) {
            return arr[i + 1] - 1
          }
        }
        i++
      }
    }
    
    // 经典35 正确
    function minNumberdisappered1(arr) {
      // write code here
      const len = arr.length
      for (let i = 1; i <= len; i++) {
        if (arr.indexOf(i) === -1) {
          return i
        }
      }
      return len + 1
    }
    
    console.log(minNumberdisappered([-1, 2, 3, 4])); //1
    console.log(minNumberdisappered([1, 2, 3, 4])); //5
    
    console.log(minNumberdisappered([-1, 200, 300, 450]), "minNumberdisappered");
    console.log(minNumberdisappered1([-1, 200, 300, 450]),"minNumberdisappered1");
    View Code

      11、从0,1,2,...,n这n+1个数中选择n个数,组成有序数组,找出这n个数中缺失的那个数

    /**
     * @description 缺失数
     * @author cq
     * @Date 2021-01-11 17:27:21
     * @LastEditTime 2021-01-11 17:31:32
     * @LastEditors cq
     */
    
    
    
    /*
      从0,1,2,...,n这n+1个数中选择n个数,组成有序数组,
      找出这n个数中缺失的那个数,要求O(n)尽可能小。
     */
    
    function solve(a) {
      for (let index = 0; index < a.length; index++) {
        const element = a[index];
        if ((element + 1) != a[index+1]){
          return element + 1
        }
      }
    }
    
    function solve1(a) {
      let index = 0
      while (a[index] + 1 === a[index + 1]) {
        index++
      }
      return a[index] + 1
    }
    
    function solve2(a) {
      // write code here
      let left = 0, right = a.length
      while (left < right) {
        const mid = left + Math.floor((right - left) / 2)
        if (a[mid] === mid) {
          left = mid + 1
        } else if (a[mid] > mid) {
          right = mid
        }
      }
      return left
    
    }
    
    console.log(solve([0, 1, 2, 3, 4, 5, 7])); //6
    View Code

       13、数组中只出现一次的数字

    /**
     * @description 数组中只出现一次的数字
     * @author cq
     * @Date 2021-01-13 20:18:49
     * @LastEditTime 2021-01-13 20:28:53
     * @LastEditors cq
     */
    
    function FindNumsAppearOnce(array) {
      // write code here
      let res = [];
      for (let index = 0; index < array.length; index++) {
        const element = array[index];
        const arr = array.filter(el => el == element);
        if (arr.length == 1) {
          res.push(arr[0])
        } else {
          continue
        }
      }
      return res
    }
    
    function FindNumsAppearOnce1(array) {
      // write code here
      // return list, 比如[a,b],其中ab是出现一次的两个数字
      let arrObj = {}
      for (let i = 0; i < array.length; i++) {
        let stringItem = array[i].toString()
        let temp = arrObj[stringItem]
        if (temp) {
          delete arrObj[stringItem]
        } else {
          arrObj[stringItem] = 1
        }
      }
      return Object.keys(arrObj)
    }
    
    console.log(FindNumsAppearOnce([2, 4, 3, 6, 3, 2, 5, 5]));
    console.log(FindNumsAppearOnce1([2, 4, 3, 6, 3, 2, 5, 5]),"FindNumsAppearOnce1");
    View Code

       14、数组中的某一个数字超过了数组长度的一半

    /**
     * @description 数组中的某一个数字超过了数组长度的一半
     * @author cq
     * @Date 2021-01-13 20:33:45
     * @LastEditTime 2021-01-13 20:44:39
     * @LastEditors cq
     */
    
    
    
    
    /*
      数组中有一个数字出现的次数超过数组长度的一半,
      请找出这个数字。例如输入一个长度为9的数组[1,2,3,2,2,2,5,4,2]。
      由于数字2在数组中出现了5次,超过数组长度的一半,因此输出2。如果不存在则输出0。
     */
    function MoreThanHalfNum_Solution(numbers) {
      // write code here
      let res = 0
      for (let index = 0; index < numbers.length; index++) {
        const element = numbers[index];
        const arr = numbers.filter(el => el == element);
        if (arr.length > (numbers.length / 2)) {
          res = arr[0]
        } else {
          continue
        }
      }
      return res
    }
    
    // 真尼玛牛逼
    function MoreThanHalfNum_Solution1(arr) {
      let sortArr = arr.sort()
      let count = 0;
      let midNum = sortArr[Math.floor(sortArr.length / 2)]
      console.log(midNum);
      for (let i = 0; i < arr.length; i++) {
        if (arr[i] === midNum) {
          count++
        }
      }
      return count > Math.floor(sortArr.length / 2) ? midNum : 0
    }
    
    console.log(MoreThanHalfNum_Solution([2, 2, 2, 2, 2, 1, 3, 4, 5])); //2
    console.log(MoreThanHalfNum_Solution1([2, 2, 2, 2, 2, 1, 3, 4, 5]),"MoreThanHalfNum_Solution1"); //2
    View Code

    闭包练习

      12、闭包打印

    /**
     * @description 参杂一个闭包看看
     * @author cq
     * @Date 2021-01-11 18:05:16
     * @LastEditTime 2021-01-11 20:01:45
     * @LastEditors cq
     */
    
    function fun(n, o) {
      console.log(o)
      return {
        fun: function (m) {
          return fun(m, n)
        }
      }
    }
    
    //注意看 最外层和最内层都有一个n
    // var a = fun(0);//undefined  此时n=0  闭包
    // a.fun(1);  //0
    // a.fun(2);  //0
    // a.fun(3)  //0
    
    // undefined--0--1--2
    // var b = fun(0).fun(1).fun(2).fun(3)
    
    
    // undefined--0     1 1
    var c = fun(0).fun(1); c.fun(2); c.fun(3)
    View Code
  • 相关阅读:
    IDEA开发 Scala 项目
    mvn编译时绕过本地jar去maven仓库下载问题
    三角化(转载)
    分布式文件服务器介绍(转载)
    VSCode 设置侧边栏字体大小
    libLas编译
    OSG编译
    vcpkg.exe安装与应用
    OpenCASCADE编译
    gl2ps编译
  • 原文地址:https://www.cnblogs.com/cq1715584439/p/14221296.html
Copyright © 2020-2023  润新知