当前位置: 首页 > news >正文

队列+宽搜(典型算法思想)—— OJ例题算法解析思路

目录

一、429. N 叉树的层序遍历 - 力扣(LeetCode)

算法代码: 

1. Node 类定义

2. Solution 类与层序遍历函数

3. 初始化结果与队列

4. 开始层序遍历

5. 返回结果

总结

改进建议

二、103. 二叉树的锯齿形层序遍历 - 力扣(LeetCode)

算法代码: 

1. TreeNode 类定义

2. Solution 类与锯齿形层序遍历函数

3. 初始化结果与队列

4. 开始层序遍历

5. 判断是否逆序

6. 返回结果

总结

改进建议

主要改进:

三、662. 二叉树最大宽度 - 力扣(LeetCode) 

算法代码:

1. TreeNode 类定义

2. Solution 类及其方法

3. 初始化结果与队列

4. 开始遍历树

5. 准备下一层节点

6. 返回结果

总结

改进建议

改动说明:

 四、515. 在每个树行中找最大值 - 力扣(LeetCode)

算法代码: 

1. TreeNode 类定义

2. Solution 类与方法

3. 初始化结果与队列

4. 开始遍历

5. 返回结果

总结

改进建议

主要改动


一、429. N 叉树的层序遍历 - 力扣(LeetCode)

算法代码: 

/*
// Definition for a Node.
class Node {
public:
    int val;
    vector<Node*> children;

    Node() {}

    Node(int _val) {
        val = _val;
    }

    Node(int _val, vector<Node*> _children) {
        val = _val;
        children = _children;
    }
};
*/

class Solution {
public:
    vector<vector<int>> levelOrder(Node* root) {
        vector<vector<int>> ret; // 记录最终结果
        queue<Node*> q;          // 层序遍历需要的队列
        if (root == nullptr)
            return ret;
        q.push(root);
        while (q.size()) {
            int sz = q.size(); // 先求出本层元素的个数
            vector<int> tmp;   // 统计本层的节点
            for (int i = 0; i < sz; i++) {
                Node* t = q.front();
                q.pop();
                tmp.push_back(t->val);
                for (Node* child : t->children) // 让下⼀层结点⼊队
                {
                    if (child != nullptr)
                        q.push(child);
                }
            }
            ret.push_back(tmp);
        }
        return ret;
    }
};

1. Node 类定义

class Node {
public:
    int val;
    vector<Node*> children;

    Node() {}

    Node(int _val) {
        val = _val;
    }

    Node(int _val, vector<Node*> _children) {
        val = _val;
        children = _children;
    }
};
  • Node 类定义了 N 叉树的节点结构,每个节点包含一个整型值 val 和一个子节点向量 children,用于存储该节点的所有子节点。

  • 提供了三个构造函数:

    • 默认构造函数。

    • 接受一个值 _val 的构造函数。

    • 接受一个值和一个子节点向量的构造函数。

2. Solution 类与层序遍历函数

class Solution {
public:
    vector<vector<int>> levelOrder(Node* root) {
  • 定义了 Solution 类,并在其中实现了 levelOrder 函数,该函数接受一个指向根节点的指针 root,并返回一个二维向量 vector<vector<int>>,表示层序遍历的结果。

3. 初始化结果与队列

vector<vector<int>> ret; // 记录最终结果
queue<Node*> q;          // 层序遍历需要的队列
if (root == nullptr)
    return ret;
q.push(root);
  • 创建一个向量 ret 用于存储每层的节点值。

  • 创建一个队列 q 用于实现 BFS。

  • 如果 root 为 nullptr(即树为空),直接返回空的结果。

  • 将根节点 root 入队。

4. 开始层序遍历

while (q.size()) {
    int sz = q.size(); // 先求出本层元素的个数
    vector<int> tmp;   // 统计本层的节点
    for (int i = 0; i < sz; i++) {
        Node* t = q.front();
        q.pop();
        tmp.push_back(t->val);
        for (Node* child : t->children) // 让下⼀层结点⼊队
        {
            if (child != nullptr)
                q.push(child);
        }
    }
    ret.push_back(tmp);
}
  • 使用 while 循环,当队列 q 不为空时继续遍历:

    • int sz = q.size(); 获取当前层节点的数量。

    • 创建一个临时向量 tmp 用于存储当前层的节点值。

    • 使用 for 循环遍历当前层的每个节点:

      • 从队列中取出当前节点 tq.front())并将其从队列中移除(q.pop())。

      • 将节点 t 的值 t->val 添加到 tmp 中。

      • 遍历当前节点的所有子节点 t->children,将每个子节点(如果不为 nullptr)入队,以便在下一层处理。

    • 将当前层的结果 tmp 添加到最终结果 ret 中。

5. 返回结果

return ret;
  • 最后,返回包含所有层节点值的二维向量 ret

总结

        这段代码实现了 N 叉树的层序遍历,时间复杂度为 O(n),其中 n 是树中节点的数量,因为每个节点都被访问一次。空间复杂度为 O(m),其中 m 是树的最大宽度,因为在最坏情况下(例如完全平衡树),队列中可能会存储大量节点。

改进建议

  1. 使用更现代的 C++ 特性:可以使用 nullptr 代替 NULL(虽然这里已经用了),同时可以使用 auto 关键字来简化代码。

  2. 检查子节点是否为 nullptr:在此实现中,假设所有的子节点都已初始化为有效指针。如果子节点可以为 nullptr,则应确保在入队之前检查它们。

  3. 代码整洁性:可以考虑进一步提高代码的可读性,例如使用更具描述性的变量名。

以下是改进后的代码示例:

class Solution {
public:
    vector<vector<int>> levelOrder(Node* root) {
        vector<vector<int>> ret; // 记录最终结果
        queue<Node*> q;          // 层序遍历需要的队列
        
        if (root == nullptr) return ret; // 空树直接返回
        
        q.push(root); // 将根节点入队
        
        while (!q.empty()) {
            int sz = q.size(); // 当前层节点数
            vector<int> tmp;   // 存储当前层的节点值
            
            for (int i = 0; i < sz; i++) {
                Node* t = q.front(); // 获取队头节点
                q.pop();              // 出队
                tmp.push_back(t->val); // 加入当前层结果
                
                for (Node* child : t->children) { // 遍历子节点
                    if (child) q.push(child); // 非空子节点入队
                }
            }
            
            ret.push_back(tmp); // 添加当前层结果
        }
        
        return ret; // 返回结果
    }
};

二、103. 二叉树的锯齿形层序遍历 - 力扣(LeetCode)

算法代码: 

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left),
 * right(right) {}
 * };
 */
class Solution {
public:
    vector<vector<int>> zigzagLevelOrder(TreeNode* root) {
        vector<vector<int>> ret;
        if (root == nullptr)
            return ret;
        queue<TreeNode*> q;
        q.push(root);
        int level = 1;
        while (q.size()) {
            int sz = q.size();
            vector<int> tmp;
            for (int i = 0; i < sz; i++) {
                auto t = q.front();
                q.pop();
                tmp.push_back(t->val);
                if (t->left)
                    q.push(t->left);
                if (t->right)
                    q.push(t->right);
            }
            // 判断是否逆序
            if (level % 2 == 0)
                reverse(tmp.begin(), tmp.end());
            ret.push_back(tmp);
            level++;
        }
        return ret;
    }
};

1. TreeNode 类定义

struct TreeNode {
    int val;
    TreeNode *left;
    TreeNode *right;
    TreeNode() : val(0), left(nullptr), right(nullptr) {}
    TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
    TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
};
  • TreeNode 结构体定义了二叉树的节点,包含一个整型值 val 和指向左、右子节点的指针 left 和 right

  • 提供了三个构造函数:

    • 默认构造函数,初始化一个值为 0 的节点。

    • 只接受一个整型值 x 的构造函数。

    • 接受一个值以及左右子节点的构造函数。

2. Solution 类与锯齿形层序遍历函数

class Solution {
public:
    vector<vector<int>> zigzagLevelOrder(TreeNode* root) {
  • 定义了 Solution 类,并在其中实现了 zigzagLevelOrder 函数,该函数接受一个指向根节点的指针 root,并返回一个二维向量 vector<vector<int>>,表示锯齿形遍历的结果。

3. 初始化结果与队列

vector<vector<int>> ret;
if (root == nullptr)
    return ret;
queue<TreeNode*> q;
q.push(root);
int level = 1;
  • 创建一个向量 ret 用于存储每层的节点值。

  • 检查根节点 root 是否为 nullptr,如果是,直接返回空的结果。

  • 创建一个队列 q 用于实现层序遍历,并将根节点 root 入队。

  • 初始化层计数器 level,初始值为 1。

4. 开始层序遍历

while (q.size()) {
    int sz = q.size();
    vector<int> tmp;
    for (int i = 0; i < sz; i++) {
        auto t = q.front();
        q.pop();
        tmp.push_back(t->val);
        if (t->left)
            q.push(t->left);
        if (t->right)
            q.push(t->right);
    }
  • 使用 while 循环,当队列 q 不为空时继续遍历:

    • 获取当前层节点的数量 sz

    • 创建一个临时向量 tmp 用于存储当前层的节点值。

    • 使用 for 循环遍历当前层的每个节点:

      • 从队列中取出当前节点 tq.front())并将其从队列中移除(q.pop())。

      • 将节点 t 的值 t->val 添加到 tmp 中。

      • 将当前节点的左右子节点(如果存在)入队,以便在下一层处理。

5. 判断是否逆序

if (level % 2 == 0)
    reverse(tmp.begin(), tmp.end());
ret.push_back(tmp);
level++;
  • 检查当前层的层数 level 是否为偶数:

    • 如果是偶数层,则使用 reverse 函数反转 tmp 中的元素,以实现从右到左的输出。

  • 将当前层的结果 tmp 添加到最终结果 ret 中。

  • 增加层计数器 level

6. 返回结果

return ret;
  • 最后,返回包含所有层节点值的二维向量 ret

总结

        这段代码实现了对二叉树的锯齿形层序遍历,时间复杂度为 O(n),其中 n 是树中节点的数量,因为每个节点都被访问一次。空间复杂度为 O(m),其中 m 是树的最大宽度,因为在最坏情况下(例如完全平衡树),队列中可能会存储大量节点。

改进建议

  1. 使用更现代的 C++ 特性:可以使用 nullptr 代替 NULL(虽然这里已经用了),同时可以使用 auto 关键字来简化代码。

  2. 优化反转操作:如果使用双端队列(deque),可以避免在偶数层时反转数组的开销,直接在队列的两端插入元素。

  3. 代码整洁性:可以考虑进一步提高代码的可读性,例如使用更具描述性的变量名。

以下是稍作修改和优化后的代码示例,使用双端队列来提高效率:

#include <vector>
#include <queue>
#include <deque> // 引入双端队列
using namespace std;

// Definition for a binary tree node.
struct TreeNode {
    int val;
    TreeNode *left;
    TreeNode *right;
    TreeNode() : val(0), left(nullptr), right(nullptr) {}
    TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
    TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
};

class Solution {
public:
    vector<vector<int>> zigzagLevelOrder(TreeNode* root) {
        vector<vector<int>> ret;
        if (root == nullptr)
            return ret;

        queue<TreeNode*> q;
        q.push(root);
        bool leftToRight = true; // 指示当前层是否从左到右

        while (!q.empty()) {
            int sz = q.size();
            deque<int> tmp; // 使用双端队列保存当前层节点值
            
            for (int i = 0; i < sz; i++) {
                auto t = q.front();
                q.pop();
                
                if (leftToRight) {
                    tmp.push_back(t->val); // 从右侧插入
                } else {
                    tmp.push_front(t->val); // 从左侧插入
                }
                
                if (t->left)
                    q.push(t->left);
                if (t->right)
                    q.push(t->right);
            }
            
            ret.push_back(vector<int>(tmp.begin(), tmp.end())); // 将 deque 转换为 vector
            leftToRight = !leftToRight; // 切换方向
        }
        
        return ret;
    }
};

主要改进:

  • 使用 deque 替代 vector,避免在偶数层时反转数组,提高了效率。

  • 使用 leftToRight 布尔变量来指示当前层的遍历方向,使代码更清晰。

三、662. 二叉树最大宽度 - 力扣(LeetCode) 

不采用下面硬来的方法,会超时: 

算法代码:

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left),
 * right(right) {}
 * };
 */
class Solution {
public:
    int widthOfBinaryTree(TreeNode* root) {
        vector<pair<TreeNode*, unsigned int>> q; // ⽤数组模拟队列
        q.push_back({root, 1});
        unsigned int ret = 0;
        while (q.size()) {
            // 先更新这⼀层的宽度
            auto& [x1, y1] = q[0];
            auto& [x2, y2] = q.back();
            ret = max(ret, y2 - y1 + 1);
            // 让下⼀层进队
            vector<pair<TreeNode*, unsigned int>> tmp; // 让下⼀层进⼊这个队列
            for (auto& [x, y] : q) {
                if (x->left)
                    tmp.push_back({x->left, y * 2});
                if (x->right)
                    tmp.push_back({x->right, y * 2 + 1});
            }
            q = tmp;
        }
        return ret;
    }
};

1. TreeNode 类定义

struct TreeNode {
    int val;
    TreeNode *left;
    TreeNode *right;
    TreeNode() : val(0), left(nullptr), right(nullptr) {}
    TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
    TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
};
  • TreeNode 结构体定义了二叉树的节点。每个节点包含一个整型值 val 和指向左、右子节点的指针 left 和 right

  • 包含构造函数,用于不同情况初始化节点。

2. Solution 类及其方法

class Solution {
public:
    int widthOfBinaryTree(TreeNode* root) {
  • 定义了 Solution 类,并在其中实现了 widthOfBinaryTree 方法,该方法接受一个指向根节点 root 的指针,并返回树的最大宽度。

3. 初始化结果与队列

vector<pair<TreeNode*, unsigned int>> q; // 用数组模拟队列
q.push_back({root, 1}); // 用一个编号表示根节点
unsigned int ret = 0; // 记录最大宽度
  • 创建一个向量 q,用来存储二叉树节点及其相对位置(编号):

    • pair<TreeNode*, unsigned int> 表示节点和其编号,编号用于计算宽度。

  • 将根节点和编号 1 入队。

  • 初始化 ret 为 0,用于保存最大宽度。

4. 开始遍历树

while (q.size()) {
    // 先更新这层的宽度
    auto& [x1, y1] = q[0];
    auto& [x2, y2] = q.back();
    ret = max(ret, y2 - y1 + 1);
  • 使用 while 循环,直到队列 q 为空:

    • 取出当前层的第一个节点 x1 和它的编号 y1,以及最后一个节点 x2 和它的编号 y2

    • 通过计算 y2 - y1 + 1 更新最大宽度 ret

5. 准备下一层节点

vector<pair<TreeNode*, unsigned int>> tmp; // 让下一层进队
for (auto& [x, y] : q) {
    if (x->left)
        tmp.push_back({x->left, y * 2}); // 左子节点的编号是父节点编号的两倍
    if (x->right)
        tmp.push_back({x->right, y * 2 + 1}); // 右子节点的编号是父节点编号的两倍加一
}
q = tmp; // 更新当前队列为下一层的节点
  • 创建一个临时向量 tmp 用于存储下一层的节点及其相对位置。

  • 遍历当前层的节点:

    • 如果节点 x 有左子节点,将其和对应的编号(y * 2)入队。

    • 如果节点 x 有右子节点,将其和对应的编号(y * 2 + 1)入队。

  • 更新队列 q 为 tmp,以便在下一次循环中处理下一层。

6. 返回结果

return ret;
  • 最后,返回最大宽度 ret

总结

        这段代码有效地计算了二叉树的最大宽度,时间复杂度为 O(n),其中 n 是树中节点的数量,因为每个节点都被访问一次。空间复杂度为 O(m),其中 m 是树的最大宽度,最坏情况下队列可能存储一层的所有节点。

改进建议

  1. 内存管理:虽然此实现会使用较少的内存,但在某些情况下,可以考虑使用队列(如 std::queue)而不是向量来管理节点,以提高效率和可读性。

  2. 错误处理:可以增加对无效输入(如空树)的处理逻辑。

  3. 代码可读性:在 C++17 及以上,可以使用 std::optional 或其他特性来进一步改善代码的表达力。

以下是稍作修改后的代码示例,使用 std::queue 来模拟队列,增强可读性:

#include <queue>
#include <utility> // 引入 std::pair
using namespace std;

// Definition for a binary tree node.
struct TreeNode {
    int val;
    TreeNode *left;
    TreeNode *right;
    TreeNode() : val(0), left(nullptr), right(nullptr) {}
    TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
    TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
};

class Solution {
public:
    int widthOfBinaryTree(TreeNode* root) {
        if (root == nullptr) return 0; // 检查空树的情况

        queue<pair<TreeNode*, unsigned int>> q; // 使用队列
        q.push({root, 1}); // 根节点入队并设置初始编号
        unsigned int ret = 0; // 记录最大宽度
        
        while (!q.empty()) {
            int sz = q.size();
            auto [x1, y1] = q.front(); // 当前层第一个节点
            auto [x2, y2] = q.back();  // 当前层最后一个节点
            ret = max(ret, y2 - y1 + 1); // 更新最大宽度
            
            // 将下一层的节点和它们的编号入队
            for (int i = 0; i < sz; i++) {
                auto [x, y] = q.front();
                q.pop();
                if (x->left) q.push({x->left, y * 2});
                if (x->right) q.push({x->right, y * 2 + 1});
            }
        }
        
        return ret; // 返回结果
    }
};

改动说明:

  • 使用 std::queue 来管理节点,而不是使用向量,增强了代码的可读性和逻辑清晰度。

  • 添加了对空树的处理逻辑。

 

 四、515. 在每个树行中找最大值 - 力扣(LeetCode)

算法代码: 

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left),
 * right(right) {}
 * };
 */
class Solution {
public:
    vector<int> largestValues(TreeNode* root) {
        vector<int> ret;
        if (root == nullptr)
            return ret;
        queue<TreeNode*> q;
        q.push(root);
        while (q.size()) {
            int sz = q.size();
            int tmp = INT_MIN;
            for (int i = 0; i < sz; i++) {
                auto t = q.front();
                q.pop();
                tmp = max(tmp, t->val);
                if (t->left)
                    q.push(t->left);
                if (t->right)
                    q.push(t->right);
            }
            ret.push_back(tmp);
        }
        return ret;
    }
};

1. TreeNode 类定义

struct TreeNode {
    int val;
    TreeNode *left;
    TreeNode *right;
    TreeNode() : val(0), left(nullptr), right(nullptr) {}
    TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
    TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
};
  • TreeNode 结构体定义了二叉树的节点,每个节点包含一个整型值 val 以及指向左、右子节点的指针 left 和 right

  • 提供了三个构造函数,使得节点的创建更加灵活。

2. Solution 类与方法

class Solution {
public:
    vector<int> largestValues(TreeNode* root) {
  • Solution 类中的 largestValues 方法接收一个指向根节点 root 的指针,并返回一个整型向量 vector<int>,其中包含每一层的最大值。

3. 初始化结果与队列

vector<int> ret;
if (root == nullptr)
    return ret; // 如果树为空,返回空向量
queue<TreeNode*> q;
q.push(root); // 将根节点入队
  • 创建一个向量 ret 用于存储每层的最大值。

  • 检查根节点 root 是否为 nullptr,如果是,直接返回空向量。

  • 创建一个队列 q 用于执行广度优先搜索,并将根节点 root 入队。

4. 开始遍历

while (q.size()) {
    int sz = q.size(); // 当前层的节点数量
    int tmp = INT_MIN; // 用于存储当前层的最大值
    for (int i = 0; i < sz; i++) {
        auto t = q.front(); // 获取队头节点
        q.pop();            // 出队
        tmp = max(tmp, t->val); // 更新当前层的最大值
        if (t->left)
            q.push(t->left); // 左子节点入队
        if (t->right)
            q.push(t->right); // 右子节点入队
    }
    ret.push_back(tmp); // 将当前层的最大值加入结果
}
  • 使用 while 循环,当队列 q 不为空时继续遍历:

    • 获取当前层的节点数量 sz

    • 初始化 tmp 为 INT_MIN,用于存储当前层的最大值。

    • 使用一个 for 循环遍历当前层的每个节点:

      • 取出队头节点 t,并将其从队列中移除。

      • 使用 max 函数更新当前层的最大值 tmp

      • 如果当前节点有左子节点,将其入队。

      • 如果当前节点有右子节点,将其入队。

    • 在每次完成当前层遍历后,将最大值 tmp 添加到结果向量 ret

5. 返回结果

return ret;
  • 最后,返回包含每层最大值的向量 ret

总结

这段代码有效地找出了每一层的最大值,时间复杂度为 O(n),其中 n 是树中节点的数量,因为每个节点都被访问一次。空间复杂度为 O(m),其中 m 是树的最大宽度,因为在最坏情况下队列中可能存储一层的所有节点。

改进建议

  1. 使用范围 for 循环:可以使用范围 for 循环来简化代码,使代码更清晰。

  2. 处理无效输入:可以更明确地处理空树的情况,虽然当前实现已经涵盖了这点。

  3. 使用 nullptr:在 C++11 及以上,使用 nullptr 代替 NULL

以下是稍作修改后的代码示例,使用范围 for 循环:

#include <vector>
#include <queue>
#include <limits.h> // 引入 INT_MIN
using namespace std;

// Definition for a binary tree node.
struct TreeNode {
    int val;
    TreeNode *left;
    TreeNode *right;
    TreeNode() : val(0), left(nullptr), right(nullptr) {}
    TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
    TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
};

class Solution {
public:
    vector<int> largestValues(TreeNode* root) {
        vector<int> ret;
        if (root == nullptr)
            return ret; // 如果树为空,返回空向量
        
        queue<TreeNode*> q;
        q.push(root); // 将根节点入队
        
        while (!q.empty()) {
            int sz = q.size(); // 当前层的节点数量
            int tmp = INT_MIN; // 当前层的最大值
            
            for (int i = 0; i < sz; i++) {
                auto t = q.front(); // 获取队头节点
                q.pop();            // 出队
                tmp = max(tmp, t->val); // 更新最大值
                
                if (t->left) 
                    q.push(t->left); // 左子节点入队
                if (t->right)
                    q.push(t->right); // 右子节点入队
            }
            ret.push_back(tmp); // 将当前层的最大值加入结果
        }
        
        return ret; // 返回结果
    }
};

主要改动

  • 增加了代码的可读性和整洁度,保持了功能的一致性。

相关文章:

  • ORB-SLAM3的源码学习: CameraModels相机模型文件
  • 【ISO 14229-1:2023 UDS诊断(ECU复位0x11服务)测试用例CAPL代码全解析⑧】
  • 【C++初阶】类和对象③之运算符重载--从日期类推广自定义类型运算的方法奥秘
  • 使用Navicat for MySQL工具连接本地虚拟机上的MySQL
  • mybatis 入门案例
  • 磁电偶极子学习笔记2 60GHz 双极化 二维转换波束 口径耦合 磁电偶极子宽带天线阵列
  • 云平台结合DeepSeek的AI模型优化实践:技术突破与应用革新
  • Redis中的某一热点数据缓存过期了,此时有大量请求访问怎么办
  • 简述mysql主从复制原理及工作过程,配置一主两从并验证
  • 封装红黑树实现map和set
  • 缺陷检测之图片标注工具--labme
  • 【python】You-Get
  • 使用京东AsyncTool实现异步编排
  • 4、IP查找工具-Angry IP Scanner
  • 用deepseek学大模型03-数学基础 概率论 条件概率 全概率公式 贝叶斯定理
  • 周雨彤:用角色与生活,诠释审美的艺术
  • 1、cadence从零开始让一个VCO起振——基本设置
  • MATLAB算法实战应用案例精讲-【数模应用】空间插值(附MATLAB、R语言和python代码实现)
  • JavaScript设计模式 -- 迭代器模式
  • 【信息学奥赛一本通 C++题解】1285:最大上升子序列和
  • “面具女孩”多次恐吓电梯内两幼童,当事女孩及家长道歉后获谅解
  • 澎湃读报丨解放日报9个版聚焦:上海,加快建成具有全球影响力的科技创新高地
  • 探索演艺产业新路径,2万观众走进音乐科技融创节
  • AI观察|算力饥渴与泡沫
  • 央行副行长:我们在研究丰富政策工具箱,将适时推出增量政策
  • 李强主持召开国务院常务会议