Skip to content

贪心算法和动态规划的区别 ​

贪心算法,当局部最优可以递推到全局最优时这个可以使用这个贪心算法 动态规划, 带记忆状态的暴力递归

C++
#include <iostream>
#include <vector>
#include <algorithm>
#include <climits>
using namespace std;

// 解法一:动态规划  O(n²) 时间, O(n) 空间
int jumpDP(const vector<int>& nums) {
    int n = nums.size();
    vector<int> dp(n, INT_MAX);
    dp[0] = 0;                                                                                                   for (int i = 1; i < n; ++i) {
        for (int j = 0; j < i; ++j) {
            if (dp[j] != INT_MAX && j + nums[j] >= i) {
                dp[i] = min(dp[i], dp[j] + 1);
            }
        }
    }
    return dp[n - 1];
}

// 解法二:贪心  O(n) 时间, O(1) 空间
int jumpGreedy(const vector<int>& nums) {
    int jumps = 0;
    int curEnd = 0;        // 当前这一跳能到的最远边界
    int farthest = 0;      // 在当前范围内试探到的下一步最远点
    for (int i = 0; i < (int)nums.size() - 1; ++i) {
        farthest = max(farthest, i + nums[i]);
        if (i == curEnd) {     // 用尽当前跳的范围,必须再跳一次
            ++jumps;
            curEnd = farthest;
        }
    }
    return jumps;
}

什么是动态规划? 典型的动态规划问题有哪些? ​

动态规划问题是一种把大问题拆解成重叠子问题,通过记录子问题的解来避免重复计算的算法思想。 一个问题能用DP,通常要满足两个特征:

  1. 最优子结构:原问题的最优解可以子问题的最优解组合而来
  2. 重叠子问题:递归求解时会反复计算相同的子问题 DP 的核心时写出状态转移方程,解题套路: 定义状态:dp[i] 或dp[i] [j] 表示什么? 状态转移方程: dp[i] 如何从之前的状态推导出来 初始化: 边界状态如和给值 遍历顺序:从前往后/从后往前/按照某种维度 典型题目: 斐波那契数列/爬楼梯 0-1 背包 完全背包 最长公共子序列 最长递增子序列 最长回文子串 编辑距离 打家劫舍 零钱兑换

常见的数据结构有哪些?各自适合什么场景 ​

数据结构决定了数据在内存中怎么组织,也直接影响增删查的效率。面试里最基础的五种是数组、链表、栈、队列和树。

数组 ​

元素在内存中连续存放,知道首地址和下标就能直接算出元素位置,所以按下标访问是 O(1)。 缺点是插入或删除中间元素时,后面的元素都要挪动,复杂度 O(n)。 适合:读多写少、需要按位置随机访问的场景。

链表 ​

由一个个节点串起来,每个节点保存数据和指向下一个节点的指针,节点在内存中分散存放。 已知位置时插入、删除只需改指针,是 O(1);但想找到第 k 个元素必须从头遍历,是 O(n)。 适合:频繁插入删除、元素数量变化大的场景。

栈 ​

后进先出(LIFO),只能在栈顶压入和弹出。 典型应用:函数调用栈、括号匹配、表达式求值、浏览器后退。

队列 ​

先进先出(FIFO),从队尾入队、从队头出队。 典型应用:任务排队、消息缓冲、广度优先搜索(BFS)。

树 ​

非线性结构,由节点和边组成,一个节点可以有多个子节点,天然适合表达层级关系,比如文件目录、组织架构。 常见变种:

  • 二叉搜索树:左小右大,查找平均 O(log n)。
  • 红黑树:自平衡的二叉搜索树,Java 的 TreeMap 就用它。
  • B+ 树:多叉、矮胖,减少磁盘 IO,是 MySQL 索引的底层结构。
  • 堆:完全二叉树,用来快速取最大或最小值,实现优先队列。

对比一览 ​

结构访问插入/删除特点
数组O(1)O(n)连续内存,随机访问快
链表O(n)O(1)(已知位置)分散存储,增删灵活
栈仅栈顶O(1)后进先出
队列仅队头O(1)先进先出
平衡树O(log n)O(log n)有序、层级

总结 ​

没有万能的数据结构,选择取决于操作特点:随机读多用数组,增删多用链表,需要“撤销/回溯”用栈,需要排队处理用队列,需要有序或层级关系用树。


📮 联系方式

微信:BuZhiCoder | QQ:1776418445 扫码添加,备注「求职」优先通过

微信二维码

基于 VitePress 搭建

🌟训练营🤖AI面试📄做简历💻刷题