第四课 递归、分治

news2024/11/16 23:53:30

文章目录

  • 第四课 递归、分治
    • lc78.子集--中等
      • 题目描述
      • 代码展示
    • lc77.组合--中等
      • 题目描述
      • 代码展示
    • lc46.全排列--中等
      • 题目描述
      • 代码展示
    • lc47.全排列II--中等
      • 题目描述
      • 代码展示
    • lc226.翻转二叉树--简单
      • 题目描述
      • 代码展示
    • lc98.验证二叉搜索树--中等
      • 题目描述
      • 代码展示
    • lc104.二叉树的最大深度--简单
      • 题目描述
      • 代码展示
    • lc104.二叉树的最小深度--简单
      • 题目描述
      • 代码展示
    • lc50.Pow(x,n)--中等
      • 题目描述
      • 代码展示
    • lc22.括号生成--中等
      • 题目描述
      • 代码展示
    • lc23.合并k个升序链表--困难
      • 题目描述
      • 代码展示

第四课 递归、分治

lc78.子集–中等

题目描述

给你一个整数数组 nums ,数组中的元素 互不相同 。返回该数组所有可能的子集(幂集)。

解集 不能 包含重复的子集。你可以按 任意顺序 返回解集。

示例 1:

输入:nums = [1,2,3]
输出:[[],[1],[2],[1,2],[3],[1,3],[2,3],[1,2,3]]

示例 2:

输入:nums = [0]
输出:[[],[0]]

提示:

  • 1 <= nums.length <= 10
  • -10 <= nums[i] <= 10
  • nums 中的所有元素 互不相同

代码展示

class Solution {
public:
    vector<int> t;            // 用于暂存当前子集
    vector<vector<int>> ans;  // 用于存储所有子集的答案

    // DFS 函数,cur 表示当前处理的元素索引,nums 表示原始数组
    void dfs(int cur, vector<int>& nums) {
        if (cur == nums.size()) {  // 如果当前索引等于数组大小,表示处理完了所有元素,将当前子集添加到答案中
            ans.push_back(t);
            return;
        }
        t.push_back(nums[cur]);    // 将当前元素加入子集
        dfs(cur + 1, nums);        // 递归处理下一个元素
        t.pop_back();              // 回溯,将当前元素从子集中移除
        dfs(cur + 1, nums);        // 继续递归处理下一个元素,不加入当前元素的情况
    }

    vector<vector<int>> subsets(vector<int>& nums) {
        dfs(0, nums);  // 从第一个元素开始递归生成子集
        return ans;    // 返回生成的所有子集
    }
};

lc77.组合–中等

题目描述

给定两个整数 nk,返回范围 [1, n] 中所有可能的 k 个数的组合。

你可以按 任何顺序 返回答案。

示例 1:

输入:n = 4, k = 2
输出:
[
  [2,4],
  [3,4],
  [2,3],
  [1,2],
  [1,3],
  [1,4],
]

示例 2:

输入:n = 1, k = 1
输出:[[1]]

提示:

  • 1 <= n <= 20
  • 1 <= k <= n

代码展示

class Solution {
public:
    vector<int> temp;           // 用于暂存当前组合
    vector<vector<int>> ans;    // 用于存储所有组合的答案

    void dfs(int cur, int n, int k) {
        // 剪枝:如果当前已经选择的数字个数加上剩下的数字个数小于 k,就不可能构造出长度为 k 的组合,进行剪枝
        if (temp.size() + (n - cur + 1) < k) {
            return;
        }
        // 如果当前已经选择的数字个数等于 k,将当前组合加入答案中
        if (temp.size() == k) {
            ans.push_back(temp);
            return;
        }
        // 考虑选择当前位置的数字
        temp.push_back(cur);
        dfs(cur + 1, n, k);
        temp.pop_back();  // 回溯,将当前位置的数字移除,考虑不选择当前位置的数字
        dfs(cur + 1, n, k);
    }

    vector<vector<int>> combine(int n, int k) {
        dfs(1, n, k);  // 从第一个数字开始生成组合
        return ans;    // 返回生成的所有组合
    }
};

优化思路:

这个算法的改进之处在于:

  1. 减少了递归的深度:在原来的算法中,即使不选择当前位置的数字,也会递归调用一次 dfs(cur + 1, n, k),导致递归深度较大。改进后的算法只有在选择当前位置的数字时才会递归调用,减少了递归深度。
  2. 减少了不必要的循环:原来的算法在循环时,遍历了所有可能的组合,包括不可能构成有效组合的情况。改进后的算法在循环时,通过限制 i 的取值范围,避免了生成无效组合的情况。

这个改进后的算法在性能上更优化,尤其是对于较大的输入,因为它减少了不必要的递归和循环操作。

class Solution {
public:
    vector<vector<int>> combine(int n, int k) {
        vector<vector<int>> result;
        vector<int> current;
        backtrack(result, current, n, k, 1);
        return result;
    }

private:
    void backtrack(vector<vector<int>>& result, vector<int>& current, int n, int k, int start) {
        if (k == 0) {
            result.push_back(current);
            return;
        }

        for (int i = start; i <= n - k + 1; ++i) { // 减去 k - 1 个数,保证剩余的数足够构成组合
            current.push_back(i);
            backtrack(result, current, n, k - 1, i + 1);
            current.pop_back();
        }
    }
};

lc46.全排列–中等

题目描述

给定一个不含重复数字的数组 nums ,返回其 所有可能的全排列 。你可以 按任意顺序 返回答案。

示例 1:

输入:nums = [1,2,3]
输出:[[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2],[3,2,1]]

示例 2:

输入:nums = [0,1]
输出:[[0,1],[1,0]]

示例 3:

输入:nums = [1]
输出:[[1]]

提示:

  • 1 <= nums.length <= 6
  • -10 <= nums[i] <= 10
  • nums 中的所有整数 互不相同

代码展示

class Solution {
public:
    void backtrack(vector<vector<int>>& res, vector<int>& output, int first, int len){
        // 所有数都填完了
        if (first == len) {
            res.emplace_back(output); // 当前排列已完成,将其添加到结果集中
            return;
        }
        for (int i = first; i < len; ++i) {
            // 动态维护数组
            swap(output[i], output[first]); // 交换当前位置与第一个位置的数字
            // 继续递归填下一个数
            backtrack(res, output, first + 1, len); // 递归填充下一个位置的数字
            // 撤销操作,即还原数组
            swap(output[i], output[first]); // 恢复交换前的数组状态,进行回溯
        }
    }
    
    vector<vector<int>> permute(vector<int>& nums) {
        vector<vector<int>> res;
        backtrack(res, nums, 0, (int)nums.size()); // 调用回溯函数开始生成全排列
        return res; // 返回所有全排列结果
    }
};

这段代码使用了递归和回溯的方法来生成全排列。具体解释如下:

  • backtrack 函数是回溯的核心部分。它接受以下参数:
    • res:存储结果的二维向量。
    • output:当前正在生成的排列。
    • first:表示当前正在处理的位置。
    • len:数组的长度,用于确定何时完成排列。
  • backtrack 函数中,首先检查是否已经生成了一个完整的排列(即 first == len)。如果是,将当前排列添加到结果集 res 中。
  • 接下来,使用一个 for 循环,从当前位置 first 开始遍历数组。对于每个位置 i,它进行了以下操作:
    • 交换 output[i]output[first],这是为了将当前位置的数字放到第一个位置,相当于固定了第一个位置的数字。
    • 然后递归调用 backtrack,处理下一个位置,即 first + 1
    • 最后,进行回溯,恢复数组状态,即再次交换 output[i]output[first],以便尝试其他数字排列。
  • 最后,在 permute 函数中,它调用了 backtrack 函数,从数组的第一个位置开始生成全排列。最终返回所有生成的全排列。

这段代码是一个经典的全排列生成算法,使用了回溯技巧,通过交换数组中的元素来生成所有可能的排列。

lc47.全排列II–中等

题目描述

给定一个可包含重复数字的序列 nums按任意顺序 返回所有不重复的全排列。

示例 1:

输入:nums = [1,1,2]
输出:
[[1,1,2],
 [1,2,1],
 [2,1,1]]

示例 2:

输入:nums = [1,2,3]
输出:[[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2],[3,2,1]]

提示:

  • 1 <= nums.length <= 8
  • -10 <= nums[i] <= 10

代码展示

class Solution {
    vector<int> vis; // 用于标记元素是否已经被使用

public:
    void backtrack(vector<int>& nums, vector<vector<int>>& ans, int idx, vector<int>& perm) {
        if (idx == nums.size()) {
            ans.emplace_back(perm); // 当前排列已完成,将其添加到结果集中
            return;
        }
        for (int i = 0; i < (int)nums.size(); ++i) {
            if (vis[i] || (i > 0 && nums[i] == nums[i - 1] && !vis[i - 1])) {
                // 跳过已使用的元素或者处理重复元素时,跳过非第一个重复元素
                continue;
            }
            perm.emplace_back(nums[i]); // 将当前元素加入当前排列
            vis[i] = 1; // 标记当前元素已使用
            backtrack(nums, ans, idx + 1, perm); // 递归处理下一个位置
            vis[i] = 0; // 回溯,标记当前元素未使用
            perm.pop_back(); // 移除当前元素,以便尝试其他可能的排列
        }
    }

    vector<vector<int>> permuteUnique(vector<int>& nums) {
        vector<vector<int>> ans;
        vector<int> perm;
        vis.resize(nums.size()); // 初始化标记数组
        sort(nums.begin(), nums.end()); // 对输入数组进行排序,以方便处理重复元素
        backtrack(nums, ans, 0, perm); // 调用回溯函数开始生成全排列
        return ans; // 返回所有生成的不重复全排列
    }
};

lc226.翻转二叉树–简单

题目描述

给你一棵二叉树的根节点 root ,翻转这棵二叉树,并返回其根节点。

示例 1:

img

输入:root = [4,2,7,1,3,6,9]
输出:[4,7,2,9,6,3,1]

示例 2:

img

输入:root = [2,1,3]
输出:[2,3,1]

示例 3:

输入:root = []
输出:[]

提示:

  • 树中节点数目范围在 [0, 100]
  • -100 <= Node.val <= 100

代码展示

/**
 * 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:
    TreeNode* invertTree(TreeNode* root) {
        if (root == nullptr) {
            return nullptr;
        }
        TreeNode* left = invertTree(root->left);
        TreeNode* right = invertTree(root->right);
        root->left = right;
        root->right = left;
        return root;
    }
};

lc98.验证二叉搜索树–中等

题目描述

给你一个二叉树的根节点 root ,判断其是否是一个有效的二叉搜索树。

有效 二叉搜索树定义如下:

  • 节点的左子树只包含 小于 当前节点的数。
  • 节点的右子树只包含 大于 当前节点的数。
  • 所有左子树和右子树自身必须也是二叉搜索树。

示例 1:

img

输入:root = [2,1,3]
输出:true

示例 2:

img

输入:root = [5,1,4,null,null,3,6]
输出:false
解释:根节点的值是 5 ,但是右子节点的值是 4 。

提示:

  • 树中节点数目范围在[1, 104]
  • -231 <= Node.val <= 231 - 1

代码展示

/**
 * 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:    //递归
    bool helper(TreeNode* root, long long lower, long long upper) {
        if (root == nullptr) {
            return true;
        }
        if (root -> val <= lower || root -> val >= upper) {
            return false;
        }
        return helper(root -> left, lower, root -> val) && helper(root -> right, root -> val, upper);
    }
    bool isValidBST(TreeNode* root) {
        return helper(root, LONG_MIN, LONG_MAX);
    }
};
/**
 * 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:     //中序遍历
    bool isValidBST(TreeNode* root) {
        stack<TreeNode*> stack;
        long long inorder = (long long)INT_MIN - 1;

        while (!stack.empty() || root != nullptr) {
            while (root != nullptr) {
                stack.push(root);
                root = root -> left;
            }
            root = stack.top();
            stack.pop();
            // 如果中序遍历得到的节点的值小于等于前一个 inorder,说明不是二叉搜索树
            if (root -> val <= inorder) {
                return false;
            }
            inorder = root -> val;
            root = root -> right;
        }
        return true;
    }
};

lc104.二叉树的最大深度–简单

题目描述

给定一个二叉树 root ,返回其最大深度。

二叉树的 最大深度 是指从根节点到最远叶子节点的最长路径上的节点数。

示例 1:

img

输入:root = [3,9,20,null,null,15,7]
输出:3

示例 2:

输入:root = [1,null,2]
输出:2

提示:

  • 树中节点的数量在 [0, 104] 区间内。
  • -100 <= Node.val <= 100

代码展示

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

/**
 * 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 maxDepth(TreeNode* root) {
        if (root == nullptr) return 0;
        return max(maxDepth(root->left), maxDepth(root->right)) + 1;
    }
};

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

/**
 * 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 maxDepth(TreeNode* root) {
        if (root == nullptr) return 0;
        queue<TreeNode*> Q;
        Q.push(root);
        int ans = 0;
        while (!Q.empty()) {
            int sz = Q.size();
            while (sz > 0) {
                TreeNode* node = Q.front();Q.pop();
                if (node->left) Q.push(node->left);
                if (node->right) Q.push(node->right);
                sz -= 1;
            }
            ans += 1;
        } 
        return ans;
    }
};

lc104.二叉树的最小深度–简单

题目描述

给定一个二叉树,找出其最小深度。

最小深度是从根节点到最近叶子节点的最短路径上的节点数量。

**说明:**叶子节点是指没有子节点的节点。

示例 1:

img

输入:root = [3,9,20,null,null,15,7]
输出:2

示例 2:

输入:root = [2,null,3,null,4,null,5,null,6]
输出:5

提示:

  • 树中节点数的范围在 [0, 105]
  • -1000 <= Node.val <= 1000

代码展示

首先可以想到使用深度优先搜索的方法,遍历整棵树,记录最小深度。

对于每一个非叶子节点,我们只需要分别计算其左右子树的最小叶子节点深度。这样就将一个大问题转化为了小问题,可以递归地解决该问题。

/**
 * 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 minDepth(TreeNode *root) {
        if (root == nullptr) {
            return 0;
        }

        if (root->left == nullptr && root->right == nullptr) {
            return 1;
        }

        int min_depth = INT_MAX;
        if (root->left != nullptr) {
            min_depth = min(minDepth(root->left), min_depth);
        }
        if (root->right != nullptr) {
            min_depth = min(minDepth(root->right), min_depth);
        }

        return min_depth + 1;
    }
};

同样,我们可以想到使用广度优先搜索的方法,遍历整棵树。

当我们找到一个叶子节点时,直接返回这个叶子节点的深度。广度优先搜索的性质保证了最先搜索到的叶子节点的深度一定最小。

/**
 * 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 minDepth(TreeNode *root) {
        if (root == nullptr) {
            return 0;
        }

        queue<pair<TreeNode *, int> > que;
        que.emplace(root, 1);
        while (!que.empty()) {
            TreeNode *node = que.front().first;
            int depth = que.front().second;
            que.pop();
            if (node->left == nullptr && node->right == nullptr) {
                return depth;
            }
            if (node->left != nullptr) {
                que.emplace(node->left, depth + 1);
            }
            if (node->right != nullptr) {
                que.emplace(node->right, depth + 1);
            }
        }

        return 0;
    }
};

lc50.Pow(x,n)–中等

题目描述

实现 pow(x, n) ,即计算 x 的整数 n 次幂函数(即,xn )。

示例 1:

输入:x = 2.00000, n = 10
输出:1024.00000

示例 2:

输入:x = 2.10000, n = 3
输出:9.26100

示例 3:

输入:x = 2.00000, n = -2
输出:0.25000
解释:2-2 = 1/22 = 1/4 = 0.25

提示:

  • -100.0 < x < 100.0
  • -231 <= n <= 231-1
  • n 是一个整数
  • 要么 x 不为零,要么 n > 0
  • -104 <= xn <= 104

代码展示

class Solution {
public:
    double myPow(double x, long long n) {
        if (n < 0) return 1 / myPow(x, -n); // 如果 n 是负数,先计算 x 的 -n 次幂,然后取其倒数
        if (n == 0) return 1; // 如果 n 等于 0,返回 1,任何数的 0 次幂都是 1
        double temp = myPow(x, n / 2); // 递归计算 x 的 n/2 次幂
        if (n % 2 == 0)
            return temp * temp; // 如果 n 是偶数,x 的 n 次幂等于 x 的 n/2 次幂的平方
        else
            return temp * temp * x; // 如果 n 是奇数,x 的 n 次幂等于 x 的 n/2 次幂的平方再乘以 x
    }
};

lc22.括号生成–中等

题目描述

数字 n 代表生成括号的对数,请你设计一个函数,用于能够生成所有可能的并且 有效的 括号组合。

示例 1:

输入:n = 3
输出:["((()))","(()())","(())()","()(())","()()()"]

示例 2:

输入:n = 1
输出:["()"]

提示:

  • 1 <= n <= 8

代码展示

image-20231007124235318

class Solution {
public:
    // 计数(统计)类的分治问题
    vector<string> generateParenthesis(int n) {
        if (n == 0) return {""};
        // if h.contains(n)
        // 记忆化,避免计算重复的generateParenthesis(n)
        if (h.find(n) != h.end()) return h[n];
        // 划分子问题标准:第一个子问题,作为不可分割的整体
        // 分段方法:(a)b
        // (a): k对括号,子问题a是k-1对括号
        // b: n-k对括号
        vector<string> result;
        // 不同的k之间:加法原理
        for (int k = 1; k <= n; k++) {
            vector<string> result_a = generateParenthesis(k - 1);
            vector<string> result_b = generateParenthesis(n - k);
            // 左右两个子问题:乘法原理
            for (string& a : result_a)
                for (string& b : result_b)
                    result.push_back("(" + a + ")" + b);
        }
        h[n] = result;
        return result;
    }

private:
    unordered_map<int, vector<string>> h;

    // (a)b
    // ((())) 拆为 a=(())  b=""
    // (())() 拆为 a=()  b=()
    // ()()() 拆为 a=""  b=()()
};

lc23.合并k个升序链表–困难

题目描述

给你一个链表数组,每个链表都已经按升序排列。

请你将所有链表合并到一个升序链表中,返回合并后的链表。

示例 1:

输入:lists = [[1,4,5],[1,3,4],[2,6]]
输出:[1,1,2,3,4,4,5,6]
解释:链表数组如下:
[
  1->4->5,
  1->3->4,
  2->6
]
将它们合并到一个有序链表中得到。
1->1->2->3->4->4->5->6

示例 2:

输入:lists = []
输出:[]

示例 3:

输入:lists = [[]]
输出:[]

提示:

  • k == lists.length
  • 0 <= k <= 10^4
  • 0 <= lists[i].length <= 500
  • -10^4 <= lists[i][j] <= 10^4
  • lists[i]升序 排列
  • lists[i].length 的总和不超过 10^4

代码展示

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode() : val(0), next(nullptr) {}
 *     ListNode(int x) : val(x), next(nullptr) {}
 *     ListNode(int x, ListNode *next) : val(x), next(next) {}
 * };
 */
class Solution {
public:      //顺序合并
    ListNode* mergeTwoLists(ListNode *a, ListNode *b) {
        if ((!a) || (!b)) return a ? a : b;
        ListNode head, *tail = &head, *aPtr = a, *bPtr = b;
        while (aPtr && bPtr) {
            if (aPtr->val < bPtr->val) {
                tail->next = aPtr; aPtr = aPtr->next;
            } else {
                tail->next = bPtr; bPtr = bPtr->next;
            }
            tail = tail->next;
        }
        tail->next = (aPtr ? aPtr : bPtr);
        return head.next;
    }

    ListNode* mergeKLists(vector<ListNode*>& lists) {
        ListNode *ans = nullptr;
        for (size_t i = 0; i < lists.size(); ++i) {
            ans = mergeTwoLists(ans, lists[i]);
        }
        return ans;
    }
};
/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode() : val(0), next(nullptr) {}
 *     ListNode(int x) : val(x), next(nullptr) {}
 *     ListNode(int x, ListNode *next) : val(x), next(next) {}
 * };
 */
class Solution {
public:       //分治合并
    ListNode* mergeTwoLists(ListNode *a, ListNode *b) {
        if ((!a) || (!b)) return a ? a : b;
        ListNode head, *tail = &head, *aPtr = a, *bPtr = b;
        while (aPtr && bPtr) {
            if (aPtr->val < bPtr->val) {
                tail->next = aPtr; aPtr = aPtr->next;
            } else {
                tail->next = bPtr; bPtr = bPtr->next;
            }
            tail = tail->next;
        }
        tail->next = (aPtr ? aPtr : bPtr);
        return head.next;
    }

    ListNode* merge(vector <ListNode*> &lists, int l, int r) {
        if (l == r) return lists[l];
        if (l > r) return nullptr;
        int mid = (l + r) >> 1;
        return mergeTwoLists(merge(lists, l, mid), merge(lists, mid + 1, r));
    }

    ListNode* mergeKLists(vector<ListNode*>& lists) {
        return merge(lists, 0, lists.size() - 1);
    }
};

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1065737.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

八、Thymeleaf链接表达式

链接表达式使用&#xff20;符开头&#xff0c;用于描述一个URL&#xff0c;url可以是相对的&#xff0c;也可以是绝对的。当为相对路径时&#xff0c;此表达式用于在指定的URI前拼接项目的根路径&#xff0c;相当于request.getContextPath()。当为绝对路径时&#xff0c;路径按…

纳百川冲刺创业板上市:计划募资约8亿元,宁德时代为主要合作方

近日&#xff0c;纳百川新能源股份有限公司&#xff08;下称“纳百川”&#xff09;向深交所创业板递交的上市申请材料获得受理&#xff0c;浙商证券为其独家保荐人。 本次冲刺上市&#xff0c;纳百川计划募资8.29亿元&#xff0c;将用于纳百川&#xff08;滁州&#xff09;新能…

【力扣-每日一题】901. 股票价格跨度

暴力解法&#xff1a; class StockSpanner { private:vector<int> pri; public:StockSpanner() {}int next(int price) {pri.emplace_back(price);int count0;for(int ipri.size()-1;i>0;i--){if(pri[i]<price)count;else break;}return count;} };/*** Your Stoc…

软件工程与计算总结(五)软件需求基础

本帖介绍软件需求涉及的诸多基本概念&#xff0c;通过对这些概念的阐述&#xff0c;剖析软件需求的来源、层次、类别、作用等重要知识~ 目录 ​编辑 一.引言 二.需求工程基础 1.简介 2.活动 3.需求获取 4.需求分析 5.需求规格说明 6.需求验证 7.需求管理 三.需求基…

第85步 时间序列建模实战:CNN回归建模

基于WIN10的64位系统演示 一、写在前面 这一期&#xff0c;我们介绍CNN回归。 同样&#xff0c;这里使用这个数据&#xff1a; 《PLoS One》2015年一篇题目为《Comparison of Two Hybrid Models for Forecasting the Incidence of Hemorrhagic Fever with Renal Syndrome i…

比特币的惊人飙升:“ 自最初定价高于零以来,价格飙升了 3,600,000,000% !“

10 月6 日是第一个比特币用户计算比特币价格的周年纪念日&#xff0c;这表明他们愿意购买或出售数字货币。 14年前的这一天&#xff0c;比特币价格诞生了。 正如比特币历史学家Pete Rizzo今天在 X 上发表的一篇文章中指出的那样 &#xff0c;”10 月 6 日是早…

【时间之外】EA交易代码入门

目录 MetaEditor简介 最简单的EA交易代码 代码编译 EA附加到图表 EA测试 EA正式上线 注意事项 本不打算写这篇文章&#xff0c;后来看到CSDN里有很多介绍交易软件的文章&#xff0c;平时也碰到很多人问我自动化交易的问题&#xff0c;还是写一篇科普文章&#xff0c;毕竟…

详细介绍区块链之挖矿

对不起&#xff0c;大家&#xff0c;这篇文章对作者来说实在是太有意义和含金量了&#xff0c;作者想把它设置为关注博主才能见全文&#xff0c;请大家理解&#xff01;如果觉得还是看不懂&#xff0c;抱歉耽误大家的时间&#xff0c;就请取消关注&#xff01;&#xff01;&…

开源即时通讯IM框架 MobileIMSDK v6.4 发布

一、更新内容简介 本次更新为次要版本更新&#xff0c;进行了若干优化&#xff08;更新历史详见&#xff1a;码云 Release Notes、Github Release Notes&#xff09;。MobileIMSDK 可能是市面上唯一同时支持 UDPTCPWebSocket 三种协议的同类开源IM框架。 二、MobileIMSDK简介…

EverWeb for Mac:轻松创建出色网站的强大网页设计软件

如果你正在寻找一款优质的网页设计软件&#xff0c;那么EverWeb for Mac绝对值得考虑。这款软件旨在为用户提供专业级的网站建设工具&#xff0c;帮助你轻松创建出令人印象深刻的网站。 在EverWeb for Mac中&#xff0c;用户可以快速轻松地创建网站布局和设计。该软件支持各种…

Linux 系统为何产生大量的 core 文件?

Author&#xff1a;rab 目录 一、问题分析二、解决方案扩展 一、问题分析 上一篇刚讲到《Docker 配置基础优化》&#xff0c;这里再补充一下。就在中秋国庆这段小长假里&#xff0c;接收到了线上服务器磁盘告警通知&#xff0c;线上服务器架构是一个 Docker Swarm 集群&#x…

flutter开发实战-video_player插件播放抖音直播实现(仅限Android端)

flutter开发实战-video_player插件播放抖音直播实现&#xff08;仅限Android端&#xff09; 在之前的开发过程中&#xff0c;遇到video_player播放视频&#xff0c;通过查看video_player插件描述&#xff0c;可以看到video_player在Android端使用exoplayer&#xff0c;在iOS端…

一个例子帮您掌握python正则re.match、re.search和re.findall的区别

在使用python正则进行字符串匹配查询时&#xff0c;最常用的三个函数是re.match、re.search和re.findall&#xff0c;在这里我就用一个例子带大家了解这三者的使用区别&#xff0c;话不多说我们直接上代码&#xff01; import re txt"test,a:123,b:1234,c:12345,hello!&…

二叉树--翻转二叉树

文章前言&#xff1a;如果有小白同学还是对于二叉树不太清楚&#xff0c;作者推荐&#xff1a;二叉树的初步认识_加瓦不加班的博客-CSDN博客 给你一棵二叉树的根节点 root &#xff0c;翻转这棵二叉树&#xff0c;并返回其根节点。 如果思路不清楚&#xff0c;请看动态页面&am…

二叉树--对称二叉树

小白同学对于二叉树还是不太了解的&#xff0c;作者推荐&#xff1a;二叉树的初步认识_加瓦不加班的博客-CSDN博客 对称二叉树-力扣 101 题 作者给的图&#xff1a; 代码&#xff1a; public boolean isSymmetric(TreeNode root) {//刚刚开始&#xff0c;传入的是顶堆的左、右…

短视频矩阵源码开发部署---技术解析

一、短视频SEO源码搜索技术需要考虑以下几点&#xff1a; 1. 关键词优化&#xff1a;通过研究目标受众的搜索习惯&#xff0c;选择合适的关键词&#xff0c;并在标题、描述、标签等元素中进行优化&#xff0c;提高视频的搜索排名。 2. 内容质量&#xff1a;优质、有吸引力的内…

通透理解FlashAttention与FlashAttention2:大模型更长上下文的关键

前言 本文最初和第一代ChatGLM-6B的内容汇总在一块&#xff0c;但为了阐述清楚FlashAttention、FlashAttention2等相关的原理&#xff0c;导致之前那篇文章越写越长&#xff0c;故特把FlashAttention相关的内容独立抽取出来成本文 且本文会和本博客内其他大模型相关的文章一样…

MXProxyPool: 动态爬虫IP池(抓取、存储、测试)

在网络爬虫开发中&#xff0c;使用爬虫IP可以帮助我们绕过访问限制&#xff0c;隐藏真实IP地址&#xff0c;提高爬取效率等。MXProxyPool是一个功能强大的动态爬虫IP池&#xff0c;它能够实现爬虫IP的抓取、存储和测试功能。本文将详细介绍MXProxyPool的使用方法&#xff0c;帮…

给 Linux0.11 添加网络通信功能 (Day1: 确认 qemu-system-i386 提供了虚拟网卡)

感觉单纯读闪客的文章&#xff0c;以及读 Linux0.11 源码&#xff0c;而不亲自动手做点什么&#xff0c;很难学会&#xff0c;还是得写代码 定个大目标&#xff1a;给 Linux0.11 添加网络通信功能 今日的小目标&#xff1a;先确认 qemu-system-i386 提供了网卡功能 here we …

深度学习-了解

1.机器学习的分类 监督学习&#xff08;Supervised Learning&#xff09;是指从已标注的训练数据中学习判断数据特征&#xff0c;并将其用于对未标注数据的判断的一种方法。无监督学习&#xff08;Unsupervised Learning&#xff09;不同于监督学习&#xff0c;它的学习算法是…