算法面试题

235 阅读1分钟

时间空间复杂度

# 时间复杂度 :运算的次数
# 空间复杂度 :占用的内存(多少个变量)

排序

排序算法   平均时间复杂度   空间复杂度
冒泡排序     O(n2)         O(1)
选择排序     O(n2)         o(1)
插入排序     o(n2)         o(1)
希尔排序     o(nlog(n))    o(1)
归并排序     o(nlog(n))    o(n)
快速排序     o(nlog(n))    o(log n)

题目0:插入排序

function insertSort(arr) {
    for (let i = 1; i < arr.length; i++) {
        //当前要处理的数
        let temp = arr[i];
        let j = i - 1;
        while (j >= 0 && arr[j] > temp) {
            //如果前一个数大于后一个数,将前一个数往后移一位
            arr[j + 1] = arr[j]
            j--
        }
        //此时的j是要处理的数排序后应该在的位置
        arr[j+1] = temp
    }
    return arr;
}

题目1:冒泡

(arr)=>{
     for(let i=arr.length-1,tmp;i>0;i--){ //遍历多少次
         for(let j=0;j<i;j++){ //每次遍历边界
             tmp=arr[j]
             if(tmp>arr[j+1]){
                 arr[j]=arr[j+1]
                 arr[j+1]=tmp
             }
         }
     }
     return arr
 }

题目2:选择排序

(arr)=>{
    for(let i=0,len=arr.length,min;i<len;i++){
        min=arr[i]  //每一次取min,与剩下元素比较,取最小交换min
        for(let j=i+1;j<len;j++){
            if(arr[j]<min){ //arr[j]与min交换
                let c=min 
                min=arr[j]
                arr[j]=c
            }
        }
        arr[i]=min //再付给arr[i]
    }
 }

题目3:快速排序

(arr)=>{
     let quickSort=(arr)=>{
         let len=arr.length
         if(len<2){
             return arr //left只有一个元素时,right只有一个元素时
         }else {
             let flag=arr[0]
             let left=[]
             let right=[]
             for(i=1,tmp;i<len;i++){
                 tmp=arr[i]
                if(tmp<flag){
                    left.push(tmp)
                }else{
                    right.push(tmp)
                }
             }
             return quickSort(left).concat(flag,quickSort(right)) 
             //left和right的数组长度都在减小
         }
     }
     return quickSort(arr)
 }

题目4:归并排序

[参考] 【拿下JS算法】:归并排序 - 知乎 (zhihu.com))

function mergeSort(arr){
    if(arr.length<2){
        return arr
    }
    const middle = Math.floor(arr.length/2)
    const left = arr.slice(0,middle)
    const right = arr.slice(middle,arr.lenght)
    return merge(mergeSort(left),mergeSort(right))
}

function merge(left,right){
    const res = []
    while(left.length && right.length){
        if(left[0]<right[0]){
            res.push(left.shift())
        }else{
            res.push(right.shift())
        }
    }
    return res
}

mergeSort([3,5,2,6,1])

栈(堆栈)

// 先进后出

队列

// 先进先出

链表

// 声明链表的节点
class Node{
    constructor(value){
        this.val=value
        this.next=undefined
    }
}
// 声明链表的数据结构
 class NodeList{
     constructor(arr){
         // 声明链表的头部节点
         let head=new Node(arr.shift())
         let next=head
         arr.forEach(item=>{
             next.next=new Node(item)
             next=next.next
         })
         return head //返回头指针
     }

 }
// 单链表反转
//单链表反转
function reverse(linkedList) {
  var head = linkedList.head
  // 一个节点或空链表
  if (head === null || head.next === null) {
    return
  }
  var p = head
  var q = p.next
  // 反转后的头点点变成尾部节点 
  head.next = null
  // 1->2->3  改成 3->2->1
  while (q) {//2
    r = q.next //3
    q.next = p  //1
    p = q //2
    q = r //3
  }
}

矩阵

arr=>{
    // 处理每一圈的数据遍历过程
    let map=(arr,r=[])=>{
        for(let i=0,len=arr.length;i<len;i++){
            if(i===0){ //第一行
                r=r.concat(arr[i])
            }else if(i===len-1){ //最后一行
                r=r.concat(arr[i].reverse())
            }else{ // 其它每行的最后一个元素
                r.push(arr[i].pop())
            }
        }
        arr.shift()
        arr.pop()
        // 其它每行的第一个元素
        for(let i=arr.length-1;i>=0;i--){
            r.push(arr[i].shift())
        }
        if(arr.length){ //边界条件
            map(arr,r)
        }else{
            return r
        }
    }
}

二叉树

矩阵

贪心算法

递归

路线规划

波兰式