仲灏小栈 仲灏小栈
首页
大前端
后端&运维
其他技术
生活
关于我
收藏
  • 分类
  • 标签
  • 归档
GitHub (opens new window)

仲灏

诚意, 正心, 格物, 致知
首页
大前端
后端&运维
其他技术
生活
关于我
收藏
  • 分类
  • 标签
  • 归档
GitHub (opens new window)
  • 《前端项目基础建设》
  • HTML&CSS

  • JavaScript&TypeScript

  • Node

  • 构建

  • Vue

  • React

  • 小程序

  • 跨端

  • Electron

  • WebGL&GIS

  • 浏览器

  • 面经

    • 数据结构和算法
      • 逻辑结构 vs 物理结构
      • 动态规划
    • 项目构建
    • javascript
    • 一面
    • 三面 四面
    • 二面 三面
    • Untitled
    • 初级面试题
  • 其他

  • 大前端
  • 面经
仲灏
2022-05-05
目录

数据结构和算法

imgimgimgimgimg![img](file:////private/var/folders/kc/qf5y8bzj1wj2gc4dh1rtsvhw0000gn/T/com.kingsoft.wpsoffice.mac/wps-izhaong/ksohtml/wpsyg6aGl.png)数据结构和算法

数据结构和算法, 是大厂前端面试的“拦路虎”, 很多同学都望而生畏 。其实如果了解常用数据结构, 掌握基本的算法思维, 就 不能应对 。本章将通过多个面试题, 为你讲解算法面试题的解题思路, 同时复习常用数据结构和算法思维。

为何要考察

如果在短时间之内快速判断一个工程师是否优秀? 考察算法是最合理的方式 —— 这是业界多年的经验积累。

前端面试考算法不是因为内卷 。算法一直在后端面试中被考察, 现在前端也考查, 说明前端能做的工作越来越多了 。这是好 事。

考察的重点

算法的时间复杂度和空间复杂度

三大算法思维: 贪心, 二分, 动态规划

常见数据结构

注意事项

算法, 有难度, 轻耐心学习

不仅关注题目本身, 更要关注知识点和解题思路

按顺序学习 (本章课程按顺序设计的)

看几个面试题

列举几个代表性的面试题, 具体参考视频。

# 复杂度

  • 程序执行时需要的计算量和内存空间(和代码是否简洁无关)

  • 复杂度是数量级(方便及记忆、推广),不是具体的数字

  • 一般针对一个具体的算法,而非一个完整的系统

image-20220505150939283

# 逻辑结构 vs 物理结构

两个没有任何关系,数组可以实现栈 栈不可以实现数组

  • 栈 vs 数组

  • 栈,逻辑结构,理论模型,不管如何实现,不收任何语言的限制

  • 数组,物理结构,真实的功能实现,受限于编程语言

eg:

斐波那锲

  • /**
     * @description: 循环 O(n)
     * @author: 仲灏<izhaong@outlook.com>🌶🌶🌶
     * @return {*}
     */
    export function fibonacci(n: number): number {
        if (n <= 0) return 0;
        if (n === 1) return 1;
    
        let n1 = 1;
        let n2 = 0;
        let res = 1;
        for (let i = 2; i <= n; i++) {
            res = n1 + n2;
            n2 = n1
            n1 = res
        }
    
        return res;
    }
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20

# 动态规划

  • 把一个大问题拆分成多个小问题, 主机向下拆解
  • 用递归思路去分析问题, 再改为循环去实现
  • 算法三大思维: 贪心 二分 动态规划

eg: 将数组中的0移到末尾

  • 如输入[1,0, 3,0, 11,0],输出「1,3, 11,0, 0, 0]
  • 只移动0,其他顺序不变
  • 必须在原数组进行操作
  • 遍历数组,遇到0则 push 到数组末尾
  • 用 splice 截取掉当前元素
  • 时间复杂度是 O(n^2)—算法不可用
/**
 * @description: 时间复杂度O(n^2)
 * @author: 仲灏<izhaong@outlook.com>🌶🌶🌶
 * @param {number} arr
 * @return {*}
 */
export function moveZero1(arr: number[]): void {
    let length = arr.length
    if(!length) return
    let zeroLen = 0;
    for (let i = 0; i < length - zeroLen; i++) {
        if (arr[i] === 0) {
            arr.splice(i, 1);// 本身时间复杂度为 O(n)
            arr.push(0);
            zeroLen++;
            i--;
        }
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

eg:求连续最多的字符和次数

interface IRes {
    char: string;
    length: number;
}

/**
 * @description: 求连续最多的字符和次数(嵌套循环) O(n)
 * @author: 仲灏<izhaong@outlook.com>🌶🌶🌶
 * @param {string} str
 * @return {*}
 */
export function findContinuousChar1(str: string): IRes {
    const res: IRes = {
        char: '',
        length: 0,
    };
    const length = str.length;
    if (!length) return res;

    let tempLength = 0;
    for (let i = 0; i < length; i++) {
        tempLength = 0;

        for (let j = i; j < length; j++) {
            if (str[i] === str[j]) {
                tempLength++;
            }

            if (str[i] !== str[j] || j === length - 1) {
                if (res.length < tempLength) {
                    res.char = str[i];
                    res.length = tempLength;
                }
                if (i < length - 1) {
                    i = j - 1; // 跳步
                }
                break;
            }
        }
    }
    return res;
}

/**
 * @description: 求连续最多的字符和次数(双指针) O(n)
 * @author: 仲灏<izhaong@outlook.com>🌶🌶🌶
 * @param {string} str
 * @return {*}
 */
export function findContinuousChar2(str: string): IRes {
    const res: IRes = {
        char: '',
        length: 0,
    };
    const length = str.length;
    if (!length) return res;

    let tempLength = 0;

    let i = 0;
    let j = 0;

    for (; i < length; i++) {
        if (str[i] === str[j]) {
            tempLength++;
        }
        if (str[i] !== str[j] || i === length - 1) {
            if (tempLength > res.length) {
                res.char = str[i];
                res.length = tempLength;
            }

            tempLength = 0;
            if (i < length - 1) {
                j = i;
                i--;
            }
        }
    }

    return res;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
  • 正则表达式--- 效率非常低, 慎用
  • 累计各个元素的连续长度,最后求最大值——徒增空间复杂度
  • PS:算法题尽量用“低级〞代码,慎用语法糖或者高级 API

重点

  • 要注意实际复杂度,不要被代码表面迷惑
  • 双指针常用于解决嵌套循环
  • 算法题慎用正则表达式(实际工作可以用)

eg:

重点

  • 尽量不要转换数据结构,尤其数组这种有序结构
  • 尽量不要用内置 API,如 reverse,不好识别复杂度
  • 数字操作最快,其次是字符串
上次更新: 2022/06/05, 20:31:36
浏览器密码自动填充样式
项目构建

← 浏览器密码自动填充样式 项目构建→

最近更新
01
vim日常使用记录
04-02
02
滑动窗口最大值
04-02
03
有效的字母异位词
04-02
更多文章>
Theme by Vdoing | Copyright © 2021-2025 izhaong | github | 蜀ICP备2021031194号
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式