zoukankan      html  css  js  c++  java
  • 前端算法

    1. 二分查找和冒泡排序

    二分查找: 递归(分左右, 传递start,end参数)和非递归(使用while(l < h))

    冒泡排序: 两个for循环

    2. 快速排序

    function quickSort (arr) {
      if (arr.length < 2) return arr
      var middle = Math.floor(arr.length / 2)
      var flag = arr.splice(middle, 1)[0]
      var left = [],
            right = []
      for (var i = 0; i < arr.length; i++) {
        if (arr[i] < flag) {
          left.push(arr[i])
        } else {
          right.push(arr[i])
        }
      }
      return quickSort(left).concat([flag], quickSort(right))
    }

    3. 最长公共子串

    function findSubStr(str1, str2) {
            if (str1.length > str2.length) {
              [str1, str2] = [str2, str1]
            }
            var result = ''
            var len = str1.length
            for (var j = len; j > 0; j--) {
              for (var i = 0; i < len - j; i++) {
                result = str1.substr(i, j)
                if (str2.includes(result)) return result
              }
            }
          }
          console.log(findSubStr('aabbcc11', 'ppooiiuubcc123'))

    4. 最长公共子序列(LCS动态规划)

    // dp[i][j] 计算去最大长度,记住口诀:相等左上角加一,不等取上或左最大值
    function LCS(str1, str2){
            var rows =  str1.split("")
            rows.unshift("")
            var cols =  str2.split("")
            cols.unshift("")
            var m = rows.length
            var n = cols.length
            var dp = []
            for(var i = 0; i < m; i++){
                dp[i] = []
                for(var j = 0; j < n; j++){
                    if(i === 0 || j === 0){
                        dp[i][j] = 0
                        continue
                    }
    
                    if(rows[i] === cols[j]){
                        dp[i][j] = dp[i-1][j-1] + 1 //对角+1
                    }else{
                        dp[i][j] = Math.max( dp[i-1][j], dp[i][j-1]) //对左边,上边取最大
                    }
                }
                console.log(dp[i].join(""))//调试
            }
            return dp[i-1][j-1]
        }
    //!!!如果它来自左上角加一,则是子序列,否则向左或上回退。
    //findValue过程,其实就是和 就是把T[i][j]的计算反过来。
    // 求最长子序列
    function findValue(input1,input2,n1,n2,T){
        var i = n1-1,j=n2-1;
        var result = [];//结果保存在数组中
        console.log(i);
        console.log(j);
        while(i>0 && j>0){
            if(input1[i] == input2[j]){
                result.unshift(input1[i]);
                i--;
                j--;
            }else{
                //向左或向上回退
                if(T[i-1][j]>T[i][j-1]){
                    //向上回退
                    i--;
                }else{
                    //向左回退
                    j--;
                }
            }
    
        }
    
        console.log(result);
    }

    5. 数组去重,多种方法

    双for循环, splice剔除并i--回退

    indexOf等于index

    filter indexOf === index

    新数组indexOf === index

    使用空对象等

    6. 实现一个函数功能:sum(1,2,3,4..n)转化为 sum(1)(2)(3)(4)…(n)

    // 使用柯里化 + 递归
    function curry ( fn ) {
      var c = (...arg) => (fn.length === arg.length) ?
              fn (...arg) : (...arg1) => c(...arg, ...arg1)
      return c
    }

    7. 反转二叉树

    var invertTree = function (root) {
      if (root !== null) {
        [root.left, root.right] = [root.right, root.left]
        invertTree(root.left)
        invertTree(root.right)
      }
      return root
    }

    8. 贪心算法解决背包问题

    var items = ['A','B','C','D']
    var values = [50,220,60,60]
    var weights = [5,20,10,12]
    var capacity = 32 //背包容积
    
    greedy(values, weights, capacity) // 320
    
    function greedy(values, weights, capacity) {
            var result = 0
            var rest = capacity
            var sortArray = []
            var num = 0
            values.forEach((v, i) => {
              sortArray.push({
                value: v,
                weight: weights[i],
                ratio: v / weights[i]
              })
            })
            sortArray.sort((a, b) => b.ratio - a.ratio)
            sortArray.forEach((v, i) => {
              num = parseInt(rest / v.weight)
              rest -= num * v.weight
              result += num * v.value
            })
            return result
          }

    9. 输入一个递增排序的数组和一个数字S,在数组中查找两个数,使得他们的和正好是S,如果有多对数字的和等于S,输出两个数的乘积最小的。

    function FindNumbersWithSum(array, sum)
    {
        var index = 0
        for (var i = 0; i < array.length - 1 && array[i] < sum / 2; i++) {
            for (var j = i + 1; j < array.length; j++) {
                if (array[i] + array[j] === sum) return [array[i], array[j]]
            }
            //index = array.indexOf(sum - array[i], i + 1)
           // if (index !== -1) {
           //     return [array[i], array[index]]
            //}
        }
        return []

    10. 二叉树各种(层序)遍历

    // 根据前序和中序重建二叉树
    /* function TreeNode(x) {
        this.val = x;
        this.left = null;
        this.right = null;
    } */
    function reConstructBinaryTree(pre, vin)
    {
        var result = null
        if (pre.length === 1) {
            result = {
                val: pre[0],
                left: null,
                right: null
            }
        } else if (pre.length > 1) {
            var root = pre[0]
            var vinRootIndex = vin.indexOf(root)
            var vinLeft = vin.slice(0, vinRootIndex)
            var vinRight = vin.slice(vinRootIndex + 1, vin.length)
            pre.shift()
            var preLeft = pre.slice(0, vinLeft.length)
            var preRight = pre.slice(vinLeft.length, pre.length)
            result = {
                val: root,
                left: reConstructBinaryTree(preLeft, vinLeft),
                right: reConstructBinaryTree(preRight, vinRight)
            }
        }
        return result
    }
    
    // 递归
    // 前序遍历
    function prevTraverse (node) {
      if (node === null) return;
    
      console.log(node.data);
      prevTraverse(node.left);
      prevTraverse(node.right);
    }
    
    // 中序遍历
    function middleTraverse (node) {
      if (node === null) return;
    
      middleTraverse(node.left);
      console.log(node.data);
      middleTraverse(node.right);
    }
    
    // 后序遍历
    function lastTraverse (node) {
      if (node === null) return;
    
      lastTraverse(node.left);
      lastTraverse(node.right);
      console.log(node.data);
    }
    
    // 非递归
    // 前序遍历
    function preTraverse(tree) {
            var arr = [],
              node = null
            arr.unshift(tree)
            while (arr.length) {
              node = arr.shift()
              console.log(node.root)
              if (node.right) arr.unshift(node.right)
              if (node.left) arr.unshift(node.left)
            }
          }
    
    // 中序遍历
    function middleTraverseUnRecursion (root) {
      let arr = [],
          node = root;
    
      while (arr.length !== 0 || node !== null) {
        if (node === null) {
          node = arr.shift();
          console.log(node.data);
          node = node.right;
        } else {
          arr.unshift(node);
          node = node.left;
        }
      }
    
    }
    
    // 广度优先-层序遍历
    // 递归
    var result = []
    var stack = [tree]
    var count = 0
    var bfs = function () {
      var node = stack[count]
      if (node) {
        result.push(node.value)
        if (node.left) stack.push(node.left)
        if (node.right) stack.push(node.right)
        count++
        bfs()
      }
    }
    bfs()
    console.log(result)
    // 非递归
    function bfs (node) {
      var result = []
      var queue = []
      queue.push(node)
      while (queue.length) {
        node = queue.shift()
        result.push(node.value)
        node.left && queue.push(node.left)
        node.right && queue.push(node.right)
      }
      return result
    }

    11. 各种排序

    // 插入排序
    function insertSort(arr) {
            var temp
            for (var i = 1; i < arr.length; i++) {
              temp = arr[i]
              for (var j = i; j > 0 && temp < arr[j - 1]; j--) {
                arr[j] = arr[j - 1]
              }
              arr[j] = temp
            }
            return arr
          }
          console.log(insertSort([3, 1, 8, 2, 5]))
    
    // 归并排序
    function mergeSort(array) {
            var result = array.slice(0)
            function sort(array) {
              var length = array.length
              var mid = Math.floor(length * 0.5)
              var left = array.slice(0, mid)
              var right = array.slice(mid, length)
              if (length === 1) return array
              return merge(sort(left), sort(right))
            }
            function merge(left, right) {
              var result = []
    
              while (left.length || right.length) {
                if (left.length && right.length) {
                  if (left[0] < right[0]) {
                    result.push(left.shift())
                  } else {
                    result.push(right.shift())
                  }
                } else if (left.length) {
                  result.push(left.shift())
                } else {
                  result.push(right.shift())
                }
              }
              return result
            }
            return sort(result)
          }
          console.log(mergeSort([5, 2, 8, 3, 6]))
    
    // 二分插入排序
    function twoSort(array) {
            var len = array.length,
              i,
              j,
              tmp,
              low,
              high,
              mid,
              result
            result = array.slice(0)
            for (i = 1; i < len; i++) {
              tmp = result[i]
              low = 0
              high = i - 1
              while (low <= high) {
                mid = parseInt((high + low) / 2, 10)
                if (tmp < result[mid]) {
                  high = mid - 1
                } else {
                  low = mid + 1
                }
              }
              for (j = i - 1; j >= high + 1; j--) {
                result[j + 1] = result[j]
              }
              result[j + 1] = tmp
            }
            return result
          }
          console.log(twoSort([4, 1, 7, 2, 5]))

    12. 使用尾递归对斐波那契优化

    递归非常耗费内存,因为需要同时保存成千上百个调用帧,很容易发生“栈溢出”错误(stack overflow)。但对于尾递归来说,由于只存在一个调用帧,所以永远不会发生“栈溢出”错误。

    // 传统递归斐波那契, 会造成超时或溢出
    function Fibonacci (n) {
      if ( n <= 1 ) {return 1};
    
      return Fibonacci(n - 1) + Fibonacci(n - 2);
    }
    
    Fibonacci(10) // 89
    Fibonacci(100) // 超时
    Fibonacci(500) // 超时
    
    // 使用尾递归优化, 可规避风险
    function Fibonacci2 (n , ac1 = 1 , ac2 = 1) {
      if( n <= 1 ) {return ac2};
    
      return Fibonacci2 (n - 1, ac2, ac1 + ac2);
    }
    
    Fibonacci2(100) // 573147844013817200000
    Fibonacci2(1000) // 7.0330367711422765e+208
    Fibonacci2(10000) // Infinity

    13. 两个升序数组合并为一个升序数组

    function sort (A, B) {
      var i = 0, j = 0, p = 0, m = A.length, n = B.length, C = []
      while (i < m || j < n) {
        if (i < m && j < n) {
          C[p++] = A[i] < B[j] ? A[i++] : B[j++]
        } else if (i < m) {
          C[p++] = A[i++]
        } else {
          C[p++] = B[j++]
        }
      }
      return C
    }
  • 相关阅读:
    高斯消元学习
    HDU 4596 Yet another end of the world(解一阶不定方程)
    Codeforces Round #318 div2
    HDU 4463 Outlets(一条边固定的最小生成树)
    HDU 4458 Shoot the Airplane(计算几何 判断点是否在n边形内)
    HDU 4112 Break the Chocolate(简单的数学推导)
    HDU 4111 Alice and Bob (博弈)
    POJ 2481 Cows(线段树单点更新)
    HDU 4288 Coder(STL水过)
    zoj 2563 Long Dominoes
  • 原文地址:https://www.cnblogs.com/art-poet/p/12553742.html
Copyright © 2011-2022 走看看