前端算法题收集

  1. 数组去重和排序的多种实现算法
let ary = [12,23,12,15,25,23,25,14,16];
// es6中的Set
let arr = [...new Set(ary)]
console.log(arr)
// es6中的Array.from
let arr = Array.from(new Set(ary))
console.log(arr)
// 循环的方式
let arr = []
for(let i = 0;i < ary.length;i++){
    let item = ary[i],
    args = ary.splice(i+1)
    if(args.indexOf(item) == -1){
        arr.push(item)
    }
}
// 相邻项的处理方案
ary.sort((a,b)=>a-b)
ary = ary.join('@')+'@'
let reg = /(\d+@\1*)/g,
arr = []
ary.replace(reg,(val,group1 => {
    arr.push(Number(group1.slice(0,group1.length-1)))
    arr.push(parseFloat(group1))
}))
// 冒泡排序
function bubble(ary){
    let temp = null
    for(let i = 0;i<ary.length-1;i++){
        for(let j = 0;j<ary.length-1-i;j++){
            if(ary[j] > ary[j+1]){
                temp = ary[j]
                ary[j] = ary[j+1]
                ary[j+1] = temp
            }
        }
    }
    return ary
}
// 插入排序
function insert(ary){
    // 准备一个新数组,用来存储抓到手里的牌,开始先抓一张牌进来
    let handle = []
    handle.push(ary[0])
    // 从第二项开始依次抓牌,一直到把台面上的牌抓光
    for(let i = 1;i < ary.length;i++){
        // A是新抓的牌
        let A = ary[i]
        // 和手里的牌依次比较(从后向前比)
        for(let j = handle.length-1;j>=0;j--){
            // 每次要比较的手里的牌
            let B = handle[j]
            // 如果当前新牌A比要比较的牌B大,把A放到B的后面
            if(A>B){
                handle.splice(j+1,0,A)
                break
            }
            // 已经比到第一项,把新牌放到手中最前面
            if(j===0){
                handle.unshift(A)
            }
        }
    }
    return handle
}
// 快速排序
function quick(ary){
    // 结束递归(当ary中小于等于一项,则不用处理)
    if(ary.length <= 1){
        return ary
    }
    // 找到数组的中间项,在原有的数组中把它移除
    let middleIndex = Math.floor(ary.length / 2)
    let middleValue = ary.splice(middleIndex,1)[0]
    // 准备左右两个数组,循环剩下数组中的每一项,比当前项小的放到左边数组中,反之放到右边数组中
    let aryLefy = [],
    aryRight = []
    for(let i = 0;i<ary.length;i++){
        let item = ary[i]
        item < middleValue ? aryLeft.push(item) : aryRight.push(item)
    }
    // 递归方式让左右两边的数组持续这样处理,一直到左右两边都排好顺序为止,最后左边中间右边拼接成最后结果
    return quick(aryLeft).concat(middleValue,quick(aryRight))
}
  1. 数组扁平化的N种实现方案
let arr = [
    [1,2,2],
    [3,4,5,5],
    [6,7,8,9,[11,12,[12,13,[14]]]],10
]
// es6 无线层级扁平化
arr = arr.flat(Infinity)
// toString再转数组
arr = arr.toString().split(',').map(item=>paseFloat(item))
// 循环验证是否为数组
while(arr.some(item => Array.isArray(item))){
  arr = [].concat(...arr)
}
  1. 阿里面试题之斐波那契数列
// 方式1
function fibonacci(n){
    if(n <= 1) return 1
    let arr = [1,1]
    // 即将要创建多少个
    let i = n + 1 - 2
    while(i > 0){
        let a = arr[arr.length - 2],
        b = arr[arr.length - 1]
        arr.push(a + b)
        i--
    }
    return arr[arr.length - 1]
}
// 方式2
function fibonacci(count){
    function fn(count,curr = 1, next = 1){
        if(count == 0){
            return curr
        }else{
            return fn(count - 1,next,curr + next)
        }
    }
    return fn(count)
}
  1. 字节跳动经典算法题
/*
 * 输入一个正数N,输出所有和为N的连续正数序列
 * 例如: 输入15
 * 结果: [[1,2,3,4,5],[4,5,6],[7,8]]
*/
function createArr(n,len){
    let arr = new Array(len).fill(null),
    temp=[]
    arr[0] = n
    arr = arr.map((item,index) => {
        if(item===null){
            item = temp[index - 1] + 1
        }
        temp.push(item)
        return item
    })
    return arr
}
function fn(count){
    let result = []
    // 求出中间值
    let middle = Math.ceil(count / 2)
    // 从1开始累加
    for(let i = 1;i <= middle;i++){
        // 控制累加多少次
        for(let j = 2;;j++){
            // 求出累加多次的和
            let total = (i + (i + j - 1)) * (j / 2)
            if(total > count){
                break
            }else if(total === count){
                result.push(createArr(i,j))
                break
            }
        }
    }
    return result
}

推荐阅读更多精彩内容