前端算法大全,每日更新

github地址

数组中出现次数最多的值(数组)

  findNumber(array) {
    // Write your code here.
    let arr  = array.sort((a,b)=>a-b)
    let obj = {}
    let max 
    arr.forEach(val=>{
        if(obj[val]){
            obj[val]++
        }else{
            obj[val] = 1
        }
    })
    for(let k in obj){
        if(!max){
            max = k
        }else{
            if(obj[k]>obj[max]){
                max = k
            }
        }
    }
    return Number(max)
  }

亮起时间最长的灯 lintCode(https://www.lintcode.com/problem/1916/)(数组)

有一排 26 个彩灯,编号从 0 到 25,现在给出了一系列控制指令来控制这些彩灯的开关。
一开始这些彩灯都是关闭的,然后指令将逐条发出。
在每条指令operation[i]中含有两个整数 operation[i][0], operation[i][1]。
在接收到一条指令时,标号为 operation[i][0] 的彩灯会亮起,直到第 operation[i][1] 秒的时候熄灭。当灯熄灭后,下一条指令将会发出。也就是说,任何时候只会有一盏灯亮着。
其中第一条指令将在第0秒的时候发出,并被立刻执行。
你的任务是找到哪个彩灯单次亮起的时间最长。

function longestLightingTime(operation) {
    // write your code here
    let countTime = {}
    let currentTime = 0
    let max
    for(let i=0;i<operation.length;i++){
        let reduceTime = operation[i][1]-currentTime
        if(!countTime[operation[i][0]]){
            countTime[operation[i][0]] = reduceTime>0?reduceTime:0
        }else{
            if(reduceTime>countTime[operation[i][0]]){
                countTime[operation[i][0]] = reduceTime
            }
        }
        if(reduceTime>0){
            currentTime = operation[i][1]
        }
    }
    for(let k in countTime){
        if(!max){
            max = k
        }else if(countTime[max]<countTime[k]){
            max = k
        }
    }
    return String.fromCharCode(97+max*1)
}

字符删除(字符串)

给出两个字符串 str 和 sub,你的任务是在 str 中完全删除那些在 sub 中存在的字符。

// 精简算法(正则)
// 正则复习地址:https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/RegExp
function CharacterDeletion(str, sub) {
    let arr = [...new Set(sub.split(''))]
    return str.replace(new RegExp(arr.join('|'), 'g'), '')
}
// 常规思路,会超时(转数组)
function CharacterDeletion(str, sub) {
    // write your code here
    let arrStr = str.split('')
    let arrSub = sub.split('')
    let newArr = []
    arrStr.forEach(val=>{
        if(arrSub.indexOf(val)===-1){
            newArr.push(val)
        }
    })
    return newArr.join("")
  }

购买通行证 (https://www.lintcode.com/problem/1851/description)(数组排队问题)

亚历克斯计划参观博物馆,并在柜台购买相同的通行证。管理员决定不出售团体通行证,一次只提供一张通行证。如果访客需要一张以上的通行证,他/她必须再次重新排队到柜台并购买下一张通行证。亚历克斯想购买许多通行证。访客顺序和每位访客需要的通行证数量是已知的,亚历克斯需要多少时间才能买到所有的通行证?Alex在队列中的位置将被给定,每次交易需要1个时间单位。可以忽略每次转到行后面所需的时间。

function buyPasses(arr, k) {
    let num = 0; //记录次数
    // 不知道具体的次数循环就用while
    while (arr[k] != 0) {
        for(let i=0;i<arr.length;i++){
            if(arr[i]!==0){
                num++
                arr[i]--
                if(arr[k]===0){
                    return num
                }
            }
        }
    }
  }

数组划分 https://www.lintcode.com/problem/31/

描述
给出一个整数数组 nums 和一个整数 k。划分数组(即移动数组 nums 中的元素),使得:

  • 所有小于k的元素移到左边
  • 所有大于等于k的元素移到右边
    返回数组划分的位置,即数组中第一个位置 i,满足 nums[i] 大于等于 k。
function partitionArray(nums, k) {
    // write your code here
    // 先排序再找index
    if(nums.length===0){return 0}
    nums = nums.sort((a,b)=>a-b)
    if(nums[nums.length-1]<k){return nums.length}
    return nums.findIndex(val=>val >= k)
}

爬楼梯(https://www.lintcode.com/problem/111/solution/25683)

假设你正在爬楼梯,需要n步你才能到达顶部。但每次你只能爬一步或者两步,爬到顶部的方法有多少种?

  • 本质:斐波那契数列
// 用递归,但是空间复杂度高,耗时长
function climbStairs(n) {
    if(n<=2){
        return n
    }else{
        return climbStairs(n-1)+climbStairs(n-2)
    }
}
// 用数组来推演生成到数组n的一个次数
function climbStairs(n){
    if(n===0){
        return 0
    }else if(n<=2){
        return n
    }
    temp = [1,2]
    for(let i=2;i<n;i++){
        temp[i] = temp[i-1]+temp[i-2]
    }
    return temp[temp.length-1]
}

数组游戏

给定一个整数数组,请算出让所有元素相同的最小步数。每一步你可以选择一个元素,使得其他元素全部加1。
https://www.lintcode.com/problem/1907/description

// 找出最大值的元素,该元素不变,其他元素加1,直到全部相等,缺点:性能低
function arrayGame(arr) {
    // write your code here
    let count = 0
    while(!arr.every(val=>val === arr[0])){
        let maxIndex =arr.findIndex(val=>val===Math.max(...arr))
        for(let i=0;i<arr.length;i++){
            if(i!==maxIndex){
                arr[i]++
            }
        }
        count++
    }
    return count
}
// 步数为每个元素与最小元素的差之和
function arrayGame1(arr) {
    // write your code here
    let min = Math.min(...arr)
    return arr.reduce((sum,val)=>sum+=val-min,0)
}

所有子数组之和

function SubArraySum(nums) {
// Write your code here
    let result = 0
    let n = nums.length
    for(let i = 0;i < n;i++){
        result += (nums[i] * (i + 1) * (n - i));
    }
    return result;
}

深拷贝递归

function set (obj){
  let newobj = null
  if(typeof obj !=='object'){
    return obj
  }else if(!Array.isArray(obj)){
    newobj = {}
    for(let k in obj){
      newobj[k] = set(obj[k])
    }
  }else{
    newobj = []
    for(let i=0;i<obj.length;i++){
      newobj.push(set(obj[i]))
    }
  }
  return newobj
}

algorithm

前端算法题(每日训练+更新)

排序算法(参考https://segmentfault.com/a/1190000020072884)

冒泡排序(俩俩比较)

// 小到大
function bubbleSort (arr) {
    for(let i=0;i<arr.length-1;i++){
        for(let j=0;j<arr.length-i-1;j++){
            if(arr[j]>arr[j+1]){
                const temp = arr[j]
                arr[j] = arr[j+1]
                arr[j+1] = temp
            }
        }
    }
    return arr
}

选择排序(以最小(大)的一个元素对剩余的数组元素做比较,得到最小(大)的元素)

// 小到大
function selectionSort(arr){
    for(let i=0;i<arr.length-1;i++){
        let min = i
        for(let j=i+1;j<arr.length;j++){
            if(arr[min]>arr[j]){
                min = j
            }
        }
        let temp = arr[i]
        arr[i] = arr[min]
        arr[min] = temp
    }
    return arr
}

插入排序

//小到大,思路:分为俩部分,一部分是排序好的,一部分是未排序。先把数组第一个元素当成已经排序好的,然后拿第二个元素去比较,第一个>第二个,就二一换位,依此类推
function insertionSort(arr){
    for(let i=1;i<arr.length;i++){
        let preIndex = i-1
        let current = arr[i]
        while(preIndex>=0&&arr[preIndex]>current){
            arr[preIndex+1] = arr[preIndex]
            preIndex--
        }
        arr[preIndex+1] = current
    }
    return arr
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值