常用的基础算法(1)

总结一些常用的基础算法练习

1.冒泡排序

我们先来看一张图来理一下思路

实现

      function maoPao(arr){
        let temp = null;
        for(let i =0;i<arr.length-1;i++){
            for(let j=0;j<arr.length-1-i;j++){
                if(arr[j]>arr[j+1]){
                    temp = arr[j];
                    arr[j+1] = temp;
                    arr[j] = arr[j+1]
                }
            }
        }
        return arr;
    }
    let arr = [1,2,22,33,11,213,211]
    let aa =  maoPao(arr)
    console.log(aa) 

2.插入排序

我们也用一张图来看一下实现思路

实现

    function insertion_sort(arr) {
        var temp;
        for (var i = 1; i < arr.length; i++) {
            for (var j = i-1; j >=0; j--) {
            if (arr[j+1]<arr[j]) {
                temp=arr[j+1];
                arr[j+1]=arr[j];
                arr[j]=temp;
            }else if (arr[j+1]>=arr[j]) {
                break;
            }
            }
        }
        return arr;
        }
    let arr = [12, 8, 24, 16, 1]
    let aa = insertion_sort(arr)
    console.log(aa)

3.快速排序

思路
1.我们通过Math.floor获取中间值的下标;
2.根据下标获取到中间值;
3.让数组的每一项与中间值比较,声明left,right两个空数组;小于中间值的放left数组,大于的放right数组
4.注意要有结束递归的条件。
实现

     function  quickSort(arr) {
        if (arr.length <= 1) {
            return arr;
        }
        //向下取整 中间值的下标
        var pivotIndex = Math.floor(arr.length / 2);
        // 拿到数组的中间项 [0]是取值  并把原来数据的中间项给删除掉
        var pivot = arr.splice(pivotIndex, 1)[0];
        var left = [];
        var right = [];
        for (var i = 0; i < arr.length; i++) {
            if (arr[i] < pivot) {
                left.push(arr[i]);
            } else {
                right.push(arr[i]);
            }
        }
        return quickSort(left).concat([pivot], quickSort(right));
    };
    let bb = quickSort(arr)
    console.log(bb)
           

4.斐波那契数列

首先我们需要了解一下什么是斐波那契数列,斐波那契数列为[1,1,2,3,5,8,13,21,.....];
需要实现 fibonacci(1) => 1;fibonacci(4)=>5

实现

    function fibonacci(n){
        if(n<=1) return 1
        let arr = [1,1]
        let i = n+1-2; //已经创建两个值了 n是索引 i是要创建多少个
        while(i>0){
            let a = arr[arr.length-2],
                b = arr[arr.length-1];
            arr.push(a+b)
            i--;
        }
        return arr[arr.length-1];
    }
    console.log(fibonacci(4))  //5
    console.log(fibonacci(5))  //8
    console.log(fibonacci(11)) //144
================第二种方案==========================================
     function fibonacci1(count){
        function fn(count,curr=1,next=1){
            if(count == 0){
                return curr
            }else{
                return fn(count-1,next,curr+next)
            }
        }
        return fn(count)
    }

5.正整数数组

需求:输入一个整数N,输出所有和为N的连续整数序列,例如 输入15,
结果 [[1,2,3,4,5],[4,5,6],[7,8]]

实现

    function fn(count) {
        let result = [];
        //  求中间值
        let middle = Math.ceil(count/2);
        // 从1开始累加
        for(let i=1;i<=middle;i++){
            // 控制累加多少次 j代表多少个
            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;
    }
    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;
    }
    console.log(fn(6))
    console.log(fn(8))
    console.log(fn(15))

6.数组交集

需求:给定两个数组 写一个方法来计算他们的交集
思路:可以先对自己去重 在用下面的方法处理

实现

  function jiaoji(arr1,arr2){
        let arr = [];
        for(let i=0;i<arr1.length;i++){
            let item1 = arr1[i];
            for(let j=0;j<arr2.length;j++){
                let item2 = arr2[j]
                if(item1 == item2){
                    arr.push(item1);
                    break
                }
            }
        }console.log(arr)
        return arr;
    }
    let arr11 = [1,2,3,22,33]
    let arr22 = [2,3,111,222]
    let haha =  jiaoji(arr11,arr22)
    console.log(haha)

7.旋转数组

需求:给定一个数组,将数组中的元素向右移动k个位置 其中k是非负数
输入[1,2,3,4,5,6,7] k=3 输出[5,6,7,1,2,3,4]
解释: 第一步[7,1,2,3,4,5,6]
第二步[6,7,1,2,3,4,5]
第三部[5,6,7,1,2,3,4]

实现

    function rotate(k) {
        console.log(this)
        if (k < 0 || k === 0 || k === this.length) return this;
        if (k > this.length) k = k % this.length;
        // 旋转数组
        return this.slice(-k).concat(this.slice(0, this.length - k))

    }
    Array.prototype.rotate =rotate
    let arr = [1,2,3,4,5,6,7]
    console.log(arr.rotate(3))

8.柯理化

需求:请实现一个add函数 满足以下功能
add(1) =>1
add(1)(2) =>3
add(1)(2)(3) =>6
add(1)(2)(3)(4) =>10
add(1,2,3) =>6
add(1,2)(3) =>6
add(1)(2,3) =>6

实现

function curring(fn,length){
       length = length || fn.length;
       return function(...args){
           if(args.length>=length){
               return fn(...args)
           }
           return curring(fn.bind(null,...args),length-args.length)
       }
   }
    // 后面那个是数字是指定几个数字    
   let add = curring((...arg)=>eval(arg.join('+')),5)
   console.log(add(1,2,3,4,5))

9.柯理化函数的实现

// 函数柯里化指的是一种将使用多个参数的一个函数转换成一系列使用一个参数的函数的技术。

function curry(fn, args) {
  // 获取函数需要的参数长度
  let length = fn.length;
  args = args || [];
  return function() {
    let subArgs = args.slice(0);
    // 拼接得到现有的所有参数
    for (let i = 0; i < arguments.length; i++) {
      subArgs.push(arguments[i]);
    }
    // 判断参数的长度是否已经满足函数所需参数的长度
    if (subArgs.length >= length) {
      // 如果满足,执行函数
      return fn.apply(this, subArgs);
    } else {
      // 如果不满足,递归返回科里化的函数,等待参数的传入
      return curry.call(this, fn, subArgs);
    }
  };
}

// es6 实现
function curry(fn, ...args) {
  return fn.length <= args.length ? fn(...args) : curry.bind(null, fn, ...args);
}

10.阿里数

需求:100 以内的阿里数
对一个整数每一位求平方之和,求出数字a 在对a进行上述操,最终和等于1
82就是一个阿里数 8x8+2x2=68 6x6+64=100 1+0+0=1

实现

let aliNum=[]
    function ali(){
      for(let i = 10;i<100;i++){
          let  num = i;
          let  n = i;
        isAlNum(n,num.toString())
      }
    }
    function isAlNum(n,str){
      let  res=0;
      for(let i=0;i<str.length;i++){
          res+=str[i]*str[i]
      }
      if(res==1){
        aliNum.push(n) 
        return aliNum
      }else if(res>10){
        isAlNum(n,res.toString())
      }
    }
    ali()
    console.log(aliNum)

11.回文

求一个字符串中最长的回文
回文:前后都一样的是回文,比如aba是一个回文,qwerewq也是一个回文。

实现

function longestPalindrome(str){
   let palindromeStr=""; //记录最长回文串
   let tempPalindrome=""; //记录当前回文串
   for(let i=0;i<str.length;i++){ //i记录当前遍历字符串的开始位置,循环依次向后遍历
    tempPalindrome=""; //每次新的一轮开始时,将临时记录回文串的变量清空
    for(let j=i;j<str.length;j++){ //每次开始循环是以当前i所在的下标位置为开始遍历字符串的起始位置,直到遍历到结束位置
     tempPalindrome+=str.charAt(j); //逐个增加字符串的长度
     if(isPalindrome(tempPalindrome) && tempPalindrome.length>palindromeStr.length){ //将当前的字符串传入isPalindrome进行回文判断,如果是回文串,则判断当前回文串长度是否大于之前记录的最长回文串的长度,如果大于之前的回文串,则更新之前的记录即可
      palindromeStr=tempPalindrome; //更新回文串
     }
    }
   }
   return palindromeStr; //返回最终的最长的回文串
  }
  function isPalindrome(s){ //判断是否为回文串
   let rev=s.split('').reverse().join(''); //字符串逆转操作
   return rev===s;
  }
  //测试
  console.log(longestPalindrome("ddabbade"));//输出dabbad
posted @ 2020-08-26 09:54  爱喝可乐的靓仔  阅读(205)  评论(0编辑  收藏  举报