字节面经算法题总结

  • 时间:
  • 浏览:
  • 来源:互联网

求数组第k大的数

有两个方法:
1.直接用快速排序的思路O(nlogn)
2.快速选择,使用快速排序的思路, 递归取中间的索引进行排序, 比中间值小的放左边, 比中间值大的放右边,只需递归一个方向,O(n)

var findKthLargest = function(nums, k) {
    // quicksort(nums);
    // return nums[nums.length-k];
    return quickSelect(nums,nums.length-k,0);
};
let quicksort=arr=>{
    quick(arr,0,arr.length-1);
}
let quick=(arr,left,right)=>{
    let index;
    if(left<right){
        index=partition(arr,left,right);
        if(left<index-1){
            quick(arr,left,index-1);
        }
        if(index<right){
            quick(arr,index,right);
        }
    }
}
let partition=(arr,left,right,k)=>{
    var data=arr[Math.floor(Math.random()*(right-left+1))+left];
    let i=left,j=right;
    while(i<=j){
        while(arr[i]<data){
            i++;
        }
        while(arr[j]>data){
            j--;
        }
        if(i<j){
            swap(arr,i,j);
            i+=1;
            j-=1;
        }
    }
    return i;
}
let swap=(arr,i,j)=>{
    let temp=arr[i];
    arr[i]=arr[j];
    arr[j]=temp;
}
let quickSelect=(arr,k,start)=>{
    let left=[];
    let right=[];
    const mid=Math.floor(arr.length/2);
    const midNum=arr.splice(mid,1)[0];
    for(let i=0;i<arr.length;i++){
        if(arr[i]>midNum){
            right.push(arr[i]);
        }else{
            left.push(arr[i]);
        }
    }
    if(left.length+start===k){
        return midNum;
    }else if(left.length+start>k){
        return quickSelect(left,k,start);
    }else{
        return quickSelect(right,k,left.length+start+1);
    }
}

m位整数去掉n位后求最大值问题

function findMax(m, n) {
    m = m + ''
    let max = 0
    let lastLen = m.length - n
    function dfs(m, str, start) {
      if(str.length === lastLen) {
        max = Math.max(max, parseInt(str.join('')))
        return
      }
      for(let i = start; i < m.length; i++) {
        str.push(m[i])
        dfs(m, str.slice(), i + 1)
        str.pop()
      }
    }
    dfs(m, [], 0)
    return max
  }
  console.log(findMax(349869,3));

JS 判断对象内是否有循环引用

参考

将一个典型回调风格的功能函数变为promise风格的

在这里插入图片描述
参考

实现数组的负索引,比如arr[-1]表示数组的最后一个元素,arr[-2]倒数第二个元素,自定义类的那种

参考

let arr=[1,2,4,6,8,10];
    function Arrchange(arr){
        let proxy=new Proxy(arr,{
            set(){},
            get(arr,property){          
                if(property>=0){
                    return arr[property]
                }else{
                    return arr[(arr.length+property*1)]//*1主要是转换成数字
                }
            }
        });
        return proxy;
    }  
    let brr=new Arrchange(arr);
    console.log(brr[-1]);

实现一个Queue链式调用,1s、3s、5s后输出1,2,3;调用start才开始,调用stop可随时结束

const queue = new Queue();
queue
    .task(1000, () => {console.log(1)})
    .task(2000, () => {console.log(2)})
    .task(2000, () => {console.log(3)})
    .start()
// stop()
class Queue{
constructor() {
   this.time=0
   this.jobs=[]
   this.jobCtr=[]
}
task(wait,callback){
   this.jobs.push([wait,callback])
   return this
}
start(){
   for(const job of this.jobs){
     this.jobCtr.push(setTimeout(job[1],this.time+job[0]))
     this.time+=job[0]
   }
}
stop(){
   this.jobCtr.forEach(timer=>clearTimeout(timer))
}
}


const queue=new Queue()
queue.task(1000,()=>{console.log(1)}).task(2000,()=>{console.log(2)}).task(2000,()=>{console.log(3)}).start()
// queue.stop()

本文链接http://metronic.net.cn/metronic/show-22192.html