算法学习

155 阅读5分钟

前言

这周过的真快,又到周末,楼下的树上个星期还黄的灿烂,这周已经只剩下零星。

WechatIMG31.jpeg 加班的日子还的继续,实在是自身精力有限。一边写业务,一边改bug,一边还要被插需求,改需求,着实头疼,react的hooks 写的还是少,结合ts的部分目前大部分还是anyscript。突然发现有些时候偷懒偷懒偷着偷着自己就没了,ts的类型定义开发任务太紧,直接any,出现bug是又要仔细去看类型啊。有些技术概念不去理解,即使换成了hooks用起来也还是没有多大提效。有的时候写react 就回出现一种感觉,多了解一些概念,某些组件和业务写起来可以少写几行代码。每到这种时候就很特别的想到,多学理解和学习一些技巧,就可以少些很多代码。然而在某些事情来临时,自己依然选择原路返回。就貌似定义ts类型这个问题,业务一紧急,any吧,一看代码的时候写的什么鬼东西,下次要把类型定义弄上。下次,哈哈。我们的国语还有意思的下次一定。几次之后就明白自己已拉下了。希望接下来的开发中自己能对自己有些要求吧,尽量减少any as的出现。

工具函数

class Node {
    constructor(root,left,right){
        this.val = root;
        this.left = left;
        this.right = right;
    }
}
// 将数组转换成树
const createTree = (arr) => {
    let tree = new Node(arr[0]);
    let nodes = [tree];
    let i = 1;

    for(let node of nodes){
        // 没有值返回
        if(!node.val) return tree;
        nodes.push(node.left = new Node(arr[i]));
        i++;
        // 遍历完返回
        if(i==arr.length) return tree;
        nodes.push(node.right = new Node(arr[i]));
        i++;
        if(i==arr.length) return tree;

    }
}

// 获得平方和
function getSumSqrt(n) {
    if(!n || isNaN(n)) {
        return -1;
    }

    let s = 0
    while(n > 0) {
        s = s + (n % 10) * (n % 10);
        n = Math.floor(n / 10);
    }
    return s;
}

二叉树的直径

描述

给定一棵二叉树,你需要计算它的直径长度。一棵二叉树的直径长度是任意两个结点路径长度中的最大值。这条路径可能穿过也可能不穿过根结点。

解题思路

  • 递归结束条件确认 当节点为空的时候返回
  • 获取左右节点的最大深度
  • 将左右子树的最大深度相加,存入零时变量
  • 用临时变量和子树的最大深度比较,取最大的值,重新存入变量
  • 返回存入的变量

WechatIMG32.jpeg 1.jpg

解:

 dianeterOfBinaryTree(root) {
    let res = 0;
    const dfs = (root) => {

        if(!root) {
            return 0;
        }

        //  获取左子树的深度
        let left = dfs(root.left);
        //  获取右子树的深度
        let right  = dfs(root.right);

        //  存下每次的最深度如果比根节点大覆盖根节点的直径
        res = Math.max(res,left + right);
        //  每一层加一
        return Math.max(left, right)+1;
    }

    dfs(root);
    // 返回二叉树的直径
    return res;
}

快乐数

描述

快乐数:对于一个正整数,每一次将该数替换为它每个位置上的数字的平方和。 然后重复这个过程直到这个数变为 1,也可能是 无限循环 但始终变不到 1。 如果 可以变为  1,那么这个数就是快乐数。 如果 n 是快乐数就返回 true ;不是,则返回 false

image.png

解题思路

  • 拆解当前的数 获得平方之和
  • 循环平方拆解,最终得到1 则是快乐数
  • 否则判断拆解后的平方之和是否存在环中的数字如果存在则不是
  • 拆解当前的数 获得平方之和
  • 设置快慢指针 快指针走每次走2次,慢指针每次走1次
  • 如果快慢指针相等则说明不是快乐数
  • 慢指针如果等于1返回结果

3.jpg

4.jpg

解:

    isHappy(n) {
        let s = n; // 慢
        let q = n; // 快
        
        do { 
            s = getSumSqrt(s);
            q = getSumSqrt(q);
            q = getSumSqrt(q);
        }while(s != q)
        
        return s == 1;
    }

有效字母异位词

描述

给定两个字符串 s 和 t ,编写一个函数来判断 t 是否是 s 的字母异位词。 image.png image.png

解题思路

  1. 如果两个字符串长度不一样直接返回false
  2. 生成26个字母空间并且每个空间设置初始值为0
  3. 先遍历一次ss串中的每个字符每出现一次 累加一次
  4. 遍历tt串每出现一次减一次 如果1中空间中的值有一个小于0 那么说明不是有效字母异位词

解:

    isAnagram(s1, s2) {
    
        if(s1.length != s2.length) {
            return false;
        }
        let arr = new Array(26).fill(0);
        
        for(let i = 0; i < s1.length; i++) {
            arr[s1.codePointAt(i) - 97]++;
        }
        
        for(let j = 0; j < s2.length; j++) {
            arr[s2.codePointAt(j) - 97]--;
            
            if(arr[s2.codePointAt(j) - 97] < 0) {
                return  false;
            }
        }
        
        return true;
    }

桶排序

描述

数据排序已经很长常见了,给定一个乱序的数组,返回从小到到的排序后返回

解题思路

  • 确定桶的个数与每个桶的取值范围
  • 放入对应在的数范围的数据到对应的桶中,
  • 每个桶排序
  • 最后顺序读取桶中的内容

解:

    sort(arr) {
        //生成桶
        let min = Math.min(arr[0], ...arr);
        let max = Math.max(arr[0], ...arr);
        
        let num = parseInt((max-min) / arr.length) + 1;
        
        let numArr = new Array(num);
        
        for(let i = 0; i < num; i++) {
            numArr[i] = new Array
        }
        // 桶生成完成 
        
        // 将对的数放入对应的桶
        for(let i = 0; i < arr.length; i++) {
            let n = parseInt((arr[i] - min) / arr.length);
            numArr[n].push(arr[i]);
        }
        
        // 每个桶的自己的排序
        for(let i = 0; i < numArr.length; i++) {
            numArr[i].sort();
        }
        
        //顺序读取桶中
        let arrIndex = 0;
        for(let i = 0; i < numArr.length; i++) {
            for(let j = 0; j < numArr[i].length; j++) {
                arr[arrIndex++] = numArr[i][j]
            }
        }
        
        return arr;
        
    }