返回

庖丁解牛《剑指 Offer(专项突击版)》第1|2题,算法题从入门到进阶

前端

现在前端要求变高了,找工作的时可能会碰上算法题,每天刷几道算法题做足准备,今天是《剑指 Offer(专项突击版)》第 1 | 2 题。

动态规划:

  1. 斐波那契数列(剑指 Offer 10-I)

    动态规划是一种解决优化问题的经典算法,通过将问题分解成一系列重叠子问题,然后按照一定的顺序依次求解这些子问题,最终得到问题的整体最优解。斐波那契数列问题是动态规划的典型应用,可以通过以下步骤进行求解:

    • 将斐波那契数列的第 0 项和第 1 项设为 0 和 1。
    • 从第 2 项开始,每项等于其前两项之和。
    • 重复步骤 3,直到计算出所需的斐波那契数。

    时间复杂度:O(n)

    空间复杂度:O(1)

  2. 最长公共子序列(剑指 Offer 114)

    最长公共子序列问题是另一个常见的动态规划问题,其目标是找到两个字符串的最长公共子序列。最长公共子序列可以理解为两个字符串中的公共部分,例如“ABCD”和“ACED”的最长公共子序列是“AC”。

    • 将两个字符串划分为更小的子字符串。
    • 计算每个子字符串的公共子序列。
    • 重复步骤 3,直到计算出两个字符串的公共子序列。

    时间复杂度:O(mn)

    空间复杂度:O(mn)

贪心算法:

  1. 区间调度(剑指 Offer 45)

    贪心算法是一种贪婪的求解算法,其思想是:在每个阶段,都做出局部最优的决策,希望得到全局最优的解。区间调度问题是贪心算法的典型应用,其目标是安排一系列不重叠的区间,使得被安排的区间总数最多。

    • 将区间按照其结束时间从小到大排序。
    • 选择结束时间最早的区间。
    • 从剩余的区间中,选择与选定区间不重叠的区间,并将其添加到已选定的区间中。
    • 重复步骤 3,直到安排完所有区间。

    时间复杂度:O(n log n)

    空间复杂度:O(n)

  2. 最小覆盖子串(剑指 Offer 48)

    最小覆盖子串问题是另一个常见的贪心算法问题,其目标是找到一个字符串的最小子串,该子串包含另一个字符串的所有字符。例如,“ABCD”的最小覆盖子串是“ABC”。

    • 将包含所有字符的子串作为候选子串。
    • 从候选子串中,选择最短的子串。
    • 如果候选子串的长度大于最短子串的长度,则从候选子串中删除最左边或最右边的字符。
    • 重复步骤 3,直到候选子串的长度等于最短子串的长度。

    时间复杂度:O(n + m)

    空间复杂度:O(n)

二分查找:

  1. 旋转数组的最小数字(剑指 Offer 11)

    二分查找是一种高效的查找算法,其思想是:将一个有序数组分成两半,然后比较目标值与数组中间元素的值。如果目标值大于中间元素的值,则在数组的后一半继续查找;否则,在数组的前一半继续查找。旋转数组的最小数字问题是二分查找的典型应用,其目标是找到一个旋转数组的最小数字。

    • 将数组划分为两半。
    • 比较目标值与数组中间元素的值。
    • 如果目标值大于中间元素的值,则在数组的后一半继续查找;否则,在数组的前一半继续查找。
    • 重复步骤 3,直到找到最小数字。

    时间复杂度:O(log n)

    空间复杂度:O(1)

  2. 搜索旋转排序数组(剑指 Offer 33)

    搜索旋转排序数组问题是另一个常见的二分查找问题,其目标是找到一个旋转排序数组中的目标值。例如,在数组 [4, 5, 6, 7, 0, 1, 2] 中搜索目标值 0,其结果是 4。

    • 将数组划分为两半。
    • 比较目标值与数组中间元素的值。
    • 如果目标值大于中间元素的值,则在数组的后一半继续查找;否则,在数组的前一半继续查找。
    • 如果数组的后一半是有序的,则在数组的后一半继续查找;否则,在数组的前一半继续查找。
    • 重复步骤 3,直到找到目标值。

    时间复杂度:O(log n)

    空间复杂度:O(1)

回溯算法:

  1. 全排列(剑指 Offer 38)

    回溯算法是一种穷举搜索算法,其思想是:从问题的初始状态开始,依次尝试所有可能的解决方案,直到找到满足要求的解决方案。全排列问题是回溯算法的典型应用,其目标是找到一个集合的所有排列。

    • 从集合中选择一个元素。
    • 将选定的元素添加到排列中。
    • 从集合中删除选定的元素。
    • 重复步骤 3,直到集合为空。
    • 将排列添加到所有排列的列表中。

    时间复杂度:O(n!)

    空间复杂度:O(n)

  2. 组合(剑指 Offer 39)

    组合问题是另一个常见的回溯算法问题,其目标是找到一个集合的所有组合。例如,“ABCD”的所有组合包括“AB”、“AC”、“AD”、“BC”、“BD”、“CD”和“ABCD”。

    • 从集合中选择一个元素。
    • 将选定的元素添加到组合中。
    • 从集合中删除选定的元素。
    • 重复步骤 3,直到集合为空。
    • 将组合添加到所有组合的列表中。

    时间复杂度:O(n^k)

    空间复杂度:O(k)

树:

  1. 二叉树的后序遍历(剑指 Offer 34)

    二叉树的后序遍历是指先遍历左子树,再遍历右子树,最后遍历根结点。例如,二叉树 [1, 2, 3, 4, 5] 的后序遍历结果是 [4, 5, 2, 3, 1]。

    • 访问左子树。
    • 访问右子树。
    • 访问根结点。

    时间复杂度:O(n)

    空间复杂度:O(n)

  2. 二叉树的镜像(剑指 Offer 27)

二叉树的镜像是指将二叉树的左子树和右子树交换。例如,二叉树 [1, 2, 3, 4, 5] 的镜像是 [1, 3, 2, 5, 4]。

  • 交换根结点的左子树和右子树。
  • 对根结点的左子树和右子树分别进行镜像。

时间复杂度:O(n)

空间复杂度:O(n)

图:

  1. 最小生成树(剑指 Offer 40)

最小生成树是一种连接图中所有顶点的树,其边权和最小。最小生成树的典型应用包括网络设计、通信网络和供应链管理。

  • 将图中的所有边按照边权从小到大排序。
  • 从边权最小的边开始,依次将边添加到最小生成树中。
  • 如果添加的边会导致最小生成树中出现环,则丢弃该边。
  • 重复步骤 3,直到最小生成树中包含所有顶点。

**时间