代码随想录 -- 回溯算法

文章目录

  • 回溯算法理论
    • 什么是回溯法
    • 回溯法的效率
    • 回溯法解决的问题
    • 理解回溯法
    • 回溯法模板
  • 组合问题I
    • 描述
    • 题解
    • 优化
  • 组合总和III
    • 描述
    • 题解
  • 电话号码的字母组合
    • 描述
    • 题解
  • 组合总和
    • 描述
    • 题解
  • 组合总和II
    • 描述
    • 题解
  • 分割回文串
    • 描述
    • 题解
  • 复原IP地址
    • 描述
    • 题解
  • 子集
    • 描述
    • 题解
  • 子集II
    • 描述
    • 题解
  • 递增子序列
    • 描述
    • 题解
  • 全排列
    • 描述
    • 题解
  • 全排列 II
    • 描述
    • 题解
  • 重新安排行程 难
    • 描述
      • 如何处理死循环?
      • 映射关系的记录
    • 题解
  • N皇后 难
    • 描述
    • 题解
  • 解数独 跳过
    • 描述
    • 题解

回溯算法理论

什么是回溯法

回溯法也可以叫做回溯搜索法,它是一种搜索的方式。

回溯是递归的副产品,只要有递归就会有回溯。

回溯法的效率

纯暴力搜索

虽然回溯法很难,很不好理解,但是回溯法并不是什么高效的算法。
因为回溯的本质是穷举,穷举所有可能,然后选出我们想要的答案,如果想让回溯法高效一些,可以加一些剪枝的操作,但也改不了回溯法就是穷举的本质。

回溯法解决的问题

  • 组合问题:N个数里面按一定规则找出k个数的集合
  • 切割问题:一个字符串按一定规则有几种切割方式
  • 子集问题:一个N个数的集合里有多少符合条件的子集
  • 排列问题:N个数按一定规则全排列,有几种排列方式
  • 棋盘问题:N皇后,解数独等等

理解回溯法

回溯法解决的问题都可以抽象为树形结构

因为回溯法解决的都是在集合中递归查找子集,集合的大小就构成了树的宽度,递归的深度,都构成的树的深度。

递归就要有终止条件,所以必然是一棵高度有限的树(N叉树)。

回溯法模板

伪代码

void backtracking(参数) {if (终止条件) {存放结果;return;}for (选择:本层集合中元素(树中节点孩子的数量就是集合的大小)) {处理节点;backtracking(路径,选择列表); // 递归回溯,撤销处理结果}
}

组合问题I

题目链接

描述

给定两个整数 n 和 k,返回 1 … n 中所有可能的 k 个数的组合。

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

题解

class Solution {
private:vector<vector<int>>res;//最后的结果vector<int>path;//放单个组合void backtracking(int n,int k,int startIndex){if (path.size()==k){res.push_back(path);return;}for (int i = startIndex; i <= n; ++i) {path.push_back(i);backtracking(n,k,i+1);//使用递归代表for 一层递归一个for循环path.pop_back();}}
public:// 给定两个整数 n 和 k,返回范围 [1, n] 中所有可能的 k 个数的组合vector<vector<int>> combine(int n, int k) {backtracking(n,k,1);return res;}
};

优化

如果n=k=4 那么第一层for循环从i=2之后都毫无意义

可以剪枝的地方就在递归中每一层的for循环所选择的起始位置。

如果for循环选择的起始位置之后的元素个数 已经不足 我们需要的元素个数了,那么就没有必要搜索了。

优化过程

  • 已经存入的元素的个数:path.size()
  • 还需要的元素的个数:k-path.size()
  • 表中剩余元素的个数:n-i >= 所需元素(k - path.size())
  • 在集合n中至多要从该起始位置 : i <= n - (k - path.size()) + 1,开始遍历
    为什么有个+1呢,因为包括起始位置,我们要是一个左闭的集合。

举个例子,n = 4,k = 3, 目前已经选取的元素为0(path.size为0),n - (k - 0) + 1 即 4 - ( 3 - 0) + 1 = 2。
从2开始搜索都是合理的,可以是组合[2, 3, 4]。

class Solution {
private:vector<vector<int>>res;//最后的结果vector<int>path;//放单个组合void backtracking(int n,int k,int startIndex){if (path.size()==k){res.push_back(path);return;}for (int i = startIndex; i <= n-(k-path.size())+1; ++i) {//优化后的for循环path.push_back(i);backtracking(n,k,i+1);//使用递归代表for 一层递归一个for循环path.pop_back();}}
public:// 给定两个整数 n 和 k,返回范围 [1, n] 中所有可能的 k 个数的组合vector<vector<int>> combine(int n, int k) {backtracking(n,k,1);return res;}
};

组合总和III

题目链接

描述

找出所有相加之和为 n 的 k 个数的组合。组合中只允许含有 1 - 9 的正整数,并且每种组合中不存在重复的数字。

说明:

所有数字都是正整数。
解集不能包含重复的组合。
示例 1: 输入: k = 3, n = 7 输出: [[1,2,4]]

示例 2: 输入: k = 3, n = 9 输出: [[1,2,6], [1,3,5], [2,3,4]]

题解

class Solution {
private:vector<vector<int>> res;vector<int> path;/**** @param k 1-9之间选取的个数* @param n k个数的和为n* @param startIndex 循环开始的数* @param sum 目前已经和为多少*/void backtracking(int k, int n, int startIndex, int sum) {if (sum > n)return;if (path.size() == k) {if (sum == n)res.push_back(path);return; // 如果path.size() == k 但sum != targetSum 直接返回}for (int i = startIndex; i <= 9 - (k - path.size()) + 1; ++i) {// 剪枝path.push_back(i);sum += i;backtracking(k, n, i + 1, sum);path.pop_back();sum -= i;}}public:vector<vector<int>> combinationSum3(int k, int n) {path.clear();res.clear();backtracking(k, n, 1, 0);return res;}
};

电话号码的字母组合

题目链接

描述

给定一个仅包含数字 2-9 的字符串,返回所有它能表示的字母组合。

给出数字到字母的映射如下(与电话按键相同)。注意 1 不对应任何字母。

在这里插入图片描述
输入:“23”
输出:[“ad”, “ae”, “af”, “bd”, “be”, “bf”, “cd”, “ce”, “cf”].
说明:尽管上面的答案是按字典序排列的,但是你可以任意选择答案输出的顺序。

题解

class Solution {
private:vector<string> res;string path;vector<string>flags={"abc","def","ghi","jkl","mno","pqrs","tuv","wxyz"};void backtracking(string digits,int len,int startIndex) {if (path.size()==len){res.push_back(path);return;}string letter=flags[digits[startIndex]-'0'-2];for (int i = 0; i < letter.size(); ++i) {path.push_back(letter[i]);backtracking(digits,len,startIndex+1);path.pop_back();}}public:vector<string> letterCombinations(string digits) {int len = digits.size();if (!len)return res;backtracking(digits,len,0);return res;}
};

组合总和

题目链接

描述

给定一个无重复元素的数组 candidates 和一个目标数 target ,找出 candidates 中所有可以使数字和为 target 的组合。

candidates 中的数字可以无限制重复被选取。

说明:

所有数字(包括 target)都是正整数。
解集不能包含重复的组合。
示例 1:

输入:candidates = [2,3,6,7], target = 7,
所求解集为: [ [7], [2,2,3] ]
示例 2:

输入:candidates = [2,3,5], target = 8,
所求解集为: [ [2,2,2,2], [2,3,3], [3,5] ]

题解

class Solution {
private:vector<vector<int>> res;vector<int> path;void backtracking(vector<int> &canidates, int target, int nowSum, int startIndex) {if (nowSum > target)return;if (nowSum == target) {res.push_back(path);return;}int len = canidates.size();for (int i = startIndex; i < len; ++i) {path.push_back(canidates[i]);nowSum += canidates[i];backtracking(canidates, target, nowSum, i);path.pop_back();nowSum -= canidates[i];}}public:vector<vector<int>> combinationSum(vector<int> &candidates, int target) {backtracking(candidates, target, 0, 0);return res;}
};

组合总和II

添加链接描述

描述

给定一个数组 candidates 和一个目标数 target ,找出 candidates 中所有可以使数字和为 target 的组合。

candidates 中的每个数字在每个组合中只能使用一次。

说明: 所有数字(包括目标数)都是正整数。解集不能包含重复的组合。

示例 1:
输入: candidates = [10,1,2,7,6,1,5], target = 8,
所求解集为:
[
[1, 7],
[1, 2, 5],
[2, 6],
[1, 1, 6]
]
示例 2:
输入: candidates = [2,5,2,1,2], target = 5,
所求解集为:
[
[1,2,2],
[5]
]

题解

class Solution {
private:vector<vector<int>>res;vector<int>path;void backtracking(vector<int>&candidates,int target,int nowSum,int index){if (nowSum>target)return;if (nowSum==target){res.push_back(path);return;}for (int i = index; i < candidates.size(); ++i) {if (i>index&&candidates[i]==candidates[i-1])continue;path.push_back(candidates[i]);nowSum+=candidates[i];backtracking(candidates,target,nowSum,i+1);path.pop_back();nowSum-=candidates[i];}}
public:vector<vector<int>> combinationSum2(vector<int>& candidates, int target) {sort(candidates.begin(),candidates.end());backtracking(candidates,target,0,0);return res;}
};

分割回文串

题目链接

描述

给定一个字符串 s,将 s 分割成一些子串,使每个子串都是回文串。

返回 s 所有可能的分割方案。

示例: 输入: “aab” 输出: [ [“aa”,“b”], [“a”,“a”,“b”] ]

题解

class Solution {
private:vector<vector<string>>res;vector<string>path;bool isPalindrome(const string&s,int start,int end){for (int i = start,j=end; i < j; ++i,--j) {if (s[i]!=s[j])return false;}return true;}void backtracking(const string&s,int startIndex){// 如果起始位置已经大于s的大小,说明已经找到了一组分割方案了if (startIndex>=s.size()){res.push_back(path);return;}for (int i = startIndex; i < s.size(); ++i) {if (isPalindrome(s,startIndex,i)){// 获取[startIndex,i]在s中的子串string str=s.substr(startIndex,i-startIndex+1);path.push_back(str);}else//如果不是回文串 那么跳过continue;backtracking(s,i+1);path.pop_back();}}
public:vector<vector<string>> partition(string s) {backtracking(s,0);return res;}
};

复原IP地址

题目链接

描述

给定一个只包含数字的字符串,复原它并返回所有可能的 IP 地址格式。

有效的 IP 地址 正好由四个整数(每个整数位于 0 到 255 之间组成,且不能含有前导 0),整数之间用 ‘.’ 分隔。

例如:“0.1.2.201” 和 “192.168.1.1” 是 有效的 IP 地址,但是 “0.011.255.245”、“192.168.1.312” 和 “192.168@1.1” 是 无效的 IP 地址。

示例 1:

输入:s = “25525511135”
输出:[“255.255.11.135”,“255.255.111.35”]
示例 2:

输入:s = “0000”
输出:[“0.0.0.0”]
示例 3:

输入:s = “1111”
输出:[“1.1.1.1”]

题解

class Solution {
private:vector<string> res;// startIndex: 搜索的起始位置,pointNum:添加逗点的数量void backtracking(string &s, int startIndex, int pointNum) {if (pointNum == 3) {//逗号个数为3时 分割结束//判断第四段字符串是否合法if (vaildIP(s, startIndex, s.size() - 1)) {res.push_back(s);return;}}for (int i = startIndex; i < s.size(); ++i) {if (vaildIP(s, startIndex, i)) {// 判断 [startIndex,i] 这个区间的子串是否合法s.insert(s.begin() + i + 1, '.');//在i后面插入逗号++pointNum;backtracking(s, i + 2, pointNum);--pointNum;s.erase(s.begin() + i + 1);} else break;//不合法直接结束本层循环 因为如果这一段不合法那么再加一个字符也是不合法的}}bool vaildIP(const string &s, int start, int end) {if (start > end)return false;if (s[start] == '0' && start != end)return false;int num=0;for (int i = start; i <= end; ++i) {if (s[i]<'0'||s[i]>'9')return false;num=num*10+s[i]-'0';if (num>255)return false;}return true;}public:vector<string> restoreIpAddresses(string s) {backtracking(s, 0, 0);return res;}
};

子集

题目链接

描述

给定一组不含重复元素的整数数组 nums,返回该数组所有可能的子集(幂集)。

说明:解集不能包含重复的子集。

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

题解

class Solution {
private:vector<vector<int>>res;vector<int>subSet;void backtracking(vector<int>&nums,int startIndex){res.push_back(subSet); // 收集子集,要放在终止添加的上面,否则会漏掉自己if (startIndex>=nums.size())return;//终止条件 可以不加,因为下面的循环当startIndex==size的时候就不会进行了for (int i = startIndex; i < nums.size(); ++i) {subSet.push_back(nums[i]);backtracking(nums,i+1);subSet.pop_back();}}
public:vector<vector<int>> subsets(vector<int>& nums) {backtracking(nums,0);return res;}
};

子集II

题目链接

描述

给定一个可能包含重复元素的整数数组 nums,返回该数组所有可能的子集(幂集)。

说明:解集不能包含重复的子集。

示例:

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

题解

和子集I思路差不多,不过多了一个去重操作

class Solution {
private:vector<vector<int>>res;vector<int>path;void backtracking(vector<int>&nums,int startIndex){res.push_back(path);if (startIndex>=nums.size())return;for (int i = startIndex; i < nums.size(); ++i) {if (i>startIndex&&nums[i]==nums[i-1])continue;path.push_back(nums[i]);backtracking(nums,i+1);path.pop_back();}}
public:vector<vector<int>> subsetsWithDup(vector<int>& nums) {sort(nums.begin(),nums.end());backtracking(nums,0);return res;}
};

递增子序列

题目链接

描述

给定一个整型数组, 你的任务是找到所有该数组的递增子序列,递增子序列的长度至少是2。

示例:

输入: [4, 6, 7, 7]
输出: [[4, 6], [4, 7], [4, 6, 7], [4, 6, 7, 7], [6, 7], [6, 7, 7], [7,7], [4,7,7]]
说明:

给定数组的长度不会超过15。
数组中的整数范围是 [-100,100]。
给定数组中可能包含重复数字,相等的数字应该被视为递增的一种情况。

题解

有更好的优化 比如unordered_set换成数组 因为题目给出了数字的范围

class Solution {
private:vector<vector<int>> res;vector<int> path;void backtracking(vector<int> &nums, int startIndex) {if (path.size() >= 2) {res.push_back(path);//后面不可以加return 因为要遍历全部}unordered_set<int> uset;//uset仅负责一层 也就是一层递归调用函数for (int i = startIndex; i < nums.size(); ++i) {if (!path.empty() && nums[i] < path.back() || uset.find(nums[i]) != uset.end())continue;uset.insert(nums[i]);//记录本层本元素已经使用 不影响下一层 (下一次递归)path.push_back(nums[i]);backtracking(nums, i + 1);path.pop_back();}}public:vector<vector<int>> findSubsequences(vector<int> &nums) {backtracking(nums, 0);return res;}
};

全排列

题目链接

描述

给定一个 没有重复 数字的序列,返回其所有可能的全排列。

示例:

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

题解

排列问题:

  • 每层都是从0开始搜索而不是startIndex
  • 需要used数组记录path里都放了哪些元素了
class Solution {
private:vector<vector<int>> res;vector<int> path;void backtracking(vector<int> &nums,vector<bool>&used) {if (path.size() == nums.size()) {// 此时说明找到了一组res.push_back(path);return;}for (int i = 0; i < nums.size(); ++i) {if (used[i])continue;// path里已经收录的元素,直接跳过used[i]=true;path.push_back(nums[i]);backtracking(nums,used);used[i]=false;path.pop_back();}}public:vector<vector<int>> permute(vector<int> &nums) {vector<bool>used(nums.size(),false);backtracking(nums,used);return res;}
};

全排列 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

题解

借用代码随想录网站的图:

树层上去重(used[i - 1] == false),的树形结构如下:
在这里插入图片描述
树枝上去重(used[i - 1] == true)的树型结构如下:
在这里插入图片描述

class Solution {
private:vector<vector<int>> res;vector<int> path;void backtracking(vector<int> &nums, vector<bool> &used) {if (path.size() == nums.size()) {res.push_back(path);return;}for (int i = 0; i < nums.size(); ++i) {// used[i - 1] == true,说明同一树枝nums[i - 1]使用过// used[i - 1] == false,说明同一树层nums[i - 1]使用过// 如果同一树层nums[i - 1]使用过则直接跳过if (i > 0 && nums[i] == nums[i - 1] && used[i - 1] == false)continue;if (!used[i]) {used[i] = true;path.push_back(nums[i]);backtracking(nums, used);path.pop_back();used[i] = false;}}}public:vector<vector<int>> permuteUnique(vector<int> &nums) {vector<bool> used(nums.size(), false);sort(nums.begin(), nums.end());backtracking(nums, used);return res;}
};

重新安排行程 难

题目链接

描述

给定一个机票的字符串二维数组 [from, to],子数组中的两个成员分别表示飞机出发和降落的机场地点,对该行程进行重新规划排序。所有这些机票都属于一个从 JFK(肯尼迪国际机场)出发的先生,所以该行程必须从 JFK 开始。

提示:

如果存在多种有效的行程,请你按字符自然排序返回最小的行程组合。例如,行程 [“JFK”, “LGA”] 与 [“JFK”, “LGB”] 相比就更小,排序更靠前
所有的机场都用三个大写字母表示(机场代码)。
假定所有机票至少存在一种合理的行程。
所有的机票必须都用一次 且 只能用一次。
示例 1:

输入:[[“MUC”, “LHR”], [“JFK”, “MUC”], [“SFO”, “SJC”], [“LHR”, “SFO”]]
输出:[“JFK”, “MUC”, “LHR”, “SFO”, “SJC”]
示例 2:

输入:[[“JFK”,“SFO”],[“JFK”,“ATL”],[“SFO”,“ATL”],[“ATL”,“JFK”],[“ATL”,“SFO”]]
输出:[“JFK”,“ATL”,“JFK”,“SFO”,“ATL”,“SFO”]
解释:另一种有效的行程是 [“JFK”,“SFO”,“ATL”,“JFK”,“ATL”,“SFO”]。但是它自然排序更大更靠后。

本题中存在的几个难点

如何处理死循环?

在这里插入图片描述
出发机场和到达机场也会重复的,如果在解题的过程中没有对集合元素处理好,就会死循环

映射关系的记录

题目要求:如果有多个路径,字母序靠前排在前面

一个机场映射多个机场,多个机场之间要按照字母序排序

可以使用unordered_map<string,map<string,int>> targets ,也就是对应

map/set 自动排序(按照数字、字母序,从小到大排序)

unordered_map<出发机场,map<到达机场,航班次数>>

在遍历 unordered_map<出发机场, map<到达机场, 航班次数>> targets的过程中,可以使用"航班次数"这个字段的数字做相应的增减,来标记到达机场是否使用过了

如果“航班次数”大于零,说明目的地还可以飞,如果“航班次数”等于零说明目的地不能飞了,而不用对集合做删除元素或者增加元素的操作。

题解

class Solution {
private:unordered_map<string, map<string, int>> targets;vector<string> result;// 对于本题目而言 我们不需要遍历跟到节点的所有可能,只需要找到一个行程,就是在树形结构中唯一的一条通向叶子节点的路线// 所以需要返回值bool backtracking(vector<vector<string>> &tickets, int ticketNum) {if (ticketNum + 1 == result.size())return true;for (pair<const string, int> &target: targets[result[result.size() - 1]]) {if (target.second) {result.push_back(target.first);target.second--;if (backtracking(tickets, ticketNum))return true;target.second++;result.pop_back();}}return false;}public:vector<string> findItinerary(vector<vector<string>> &tickets) {for (const vector<string> &ticket: tickets)targets[ticket[0]][ticket[1]]++;result.push_back("JFK");backtracking(tickets, tickets.size());return result;}
};

N皇后 难

题目链接

描述

n 皇后问题 研究的是如何将 n 个皇后放置在 n×n 的棋盘上,并且使皇后彼此之间不能相互攻击。

给你一个整数 n ,返回所有不同的 n 皇后问题 的解决方案。

不能同行
不能同列
不能同斜线

每一种解法包含一个不同的 n 皇后问题 的棋子放置方案,该方案中 ‘Q’ 和 ‘.’ 分别代表了皇后和空位。
在这里插入图片描述

题解

class Solution {
private:vector<vector<string>>res;bool isValid(int row,int col,int n,vector<string>&path){//检查列for(int i = 0; i < row; ++i)if(path[i][col]=='Q')return false;/* 检查行是多余的,因为在单层搜索的过程中,每一层递归,只会选for循环(也就是同一行)里的一个元素,所以不用去重了。for(int i = 0;i < col;++i)if(path[row][i]=='Q')return false;   *///45度for(int i = col-1,j=row-1;i >= 0&&j>=0;--i,--j){if(path[j][i]=='Q')return false;}//135度for(int i = row-1,j=col+1;i>=0&&j<n ;--i,++j){if(path[i][j]=='Q')return false;}return true;}void backtracking(int n,int start,vector<string>&path){if(start==n){res.push_back(path);return;}for(int i = 0 ;i < n ;++i){if(isValid(start,i,n,path)){path[start][i]='Q';backtracking(n,start+1,path);path[start][i]='.';}}}
public:vector<vector<string>> solveNQueens(int n) {vector<string>path(n,string(n,'.'));backtracking(n,0,path);return res;}
};

解数独 跳过

题目链接

描述

编写一个程序,通过填充空格来解决数独问题。

一个数独的解法需遵循如下规则: 数字 1-9 在每一行只能出现一次。 数字 1-9 在每一列只能出现一次。 数字 1-9 在每一个以粗实线分隔的 3x3 宫内只能出现一次。 空白格用 ‘.’ 表示。
在这里插入图片描述

在这里插入图片描述
提示:

给定的数独序列只包含数字 1-9 和字符 ‘.’ 。
你可以假设给定的数独只有唯一解。
给定数独永远是 9x9 形式的。

题解

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

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

相关文章

shallowReactive浅层式响应对象

一、 reactive 和ref 都是深层响应式对象: 就是不管对象有多少层&#xff0c;修改此对象任一属性都会响应式处理 shallowReactive 和shallowRef 浅层响应式对象: 只会修改第一层对象&#xff0c;修改此对象第一层属性&#xff0c;视图会有同步变化&#xff0c;非第一层&#xf…

WorkPlus Meet局域网视频会议软件的领先解决方案

局域网视频会议软件在现代企业中发挥着重要的作用&#xff0c;而在众多选项中&#xff0c;为何选择WorkPlus Meet作为局域网视频会议软件&#xff1f; 选择局域网视频会议软件时需要考虑到企业的需求。WorkPlus Meet提供了稳定、高效的局域网视频会议功能&#xff0c;能够满足…

关于d3dx9_43.dll文件丢失的解决办法,六种详细方法

当d3dx9_43.dll文件缺失时&#xff0c;系统会显示错误信息来提示用户。这些错误信息可能会包含类似于"d3dx9_43.dll未找到"或"找不到d3dx9_43.dll"等字样。通常出现这样的字样那就是导致应用程序通常无法正常启动或执行相关功能。那么出现这样的功能有什么…

哔哩哔哩后端Java一面

前言 作者&#xff1a;晓宜 个人简介&#xff1a;互联网大厂Java准入职&#xff0c;阿里云专家博主&#xff0c;csdn后端优质创作者&#xff0c;算法爱好者 最近各大公司的春招和实习招聘都开始了&#xff0c;这里分享下去年面试B站的的一些问题&#xff0c;希望对大家有所帮助…

Centos7安装ffmpeg

Centos7安装ffmpeg 用到的包压缩并安装 用到的包 压缩并安装 tar xvJf ffmpeg-5.0.1.tar.xz yum install -y gcctar -zxvf yasm-1.3.0.tar.gz cd yasm-1.3.0 ./configure make && make install yasm --versionyum install -y bzip2tar jxvf nasm-2.14.02.tar.bz2 cd n…

Spring MVC文件上传配置

版权声明 本文原创作者&#xff1a;谷哥的小弟作者博客地址&#xff1a;http://blog.csdn.net/lfdfhl 文件上传 Spring MVC文件上传基于Servlet 3.0实现&#xff1b;示例代码如下&#xff1a; Overrideprotected void customizeRegistration(ServletRegistration.Dynamic reg…

Guitar Pro 8.1功能介绍及如何安装安装破解教程

音乐创作是许多音乐人的核心工作&#xff0c;而吉他作为其中最为常用的乐器之一&#xff0c;其创作和演奏的重要性也不言而喻。在创作过程中&#xff0c;如何更好地记录和编辑音乐成为了许多音乐人所面临的挑战。而Guitar Pro 8.1则是一款专业的吉他音乐编辑软件&#xff0c;它…

T1.数据库MySQL

二.SQL分类 2.1 DDL 2.1.1数据库操作 1). 查询所有数据库 show databases ; 2). 查询当前数据库 select database(); 3)创建数据库 create database [if not exists] 数据库名 [default charset 字符集] [collate 排序规则] ; 4&#xff09;删除数据库 drop database …

【机器学习系列】M3DM工业缺陷检测部署与训练

一.基础资料 1.Git 地址 地址 2.issues issues 3.参考 参考 csdn 二.服务器信息 1.GPU 服务器 GPU 服务器自带 CUDA 安装(前提是需要勾选上)CUDA 需要选择大于 11.3 的版本登录服务器后会自动安装 GPU 驱动 2.CUDA 安装 GPU 服务器自带 CUDA CUDA 版本查看 3.登录信…

小红书图片怎么提取?小红书图片提取原图方法!

说到小红书&#xff0c;不少女性群体都知道这个&#xff0c;他的价值很高而且变现对于大多数做自媒体的小伙伴来说&#xff0c;也是不错的选择&#xff01; 小红书对于普通大众还是互联网创作者来说&#xff0c;都太实用了&#xff0c;唯一的缺点可能就是当我们需要存储他的图…

2.VDMA视频流显示通路搭建

1.简介 本节主要讲解如何基于ZYNQ7020搭建一个视频流接收以及显示的数据通路。为后续的算法图像验证提供基础。 2.项目框架 整个项目简略框架如图&#xff0c;img_gen负责产生图像像素点&#xff0c;给到video in to AXI_Stream模块后转化为AXI_Stream数据流给到VDMA&#xff…

STM32---SG90舵机控制(HAL库,含源码)

写在前面&#xff1a;在嵌入式的项目中&#xff0c;舵机是一个十分常见的元器件模块&#xff0c;其主要的功能是实现机械转动&#xff0c;实质上舵机是一个伺服的驱动器&#xff0c;适用于那些需要角度不断变化并可以保持的控制系统。例如在机器人的电控制器系统中&#xff0c;…

用户数据的FLASH存储与应用(FPGA架构)

该系列为神经网络硬件加速器应用中涉及的模块接口部分&#xff0c;随手记录&#xff0c;以免时间久了遗忘。 一 背景 我们知道&#xff0c;在FPGA做神经网络应用加速时&#xff0c;涉及到权重参数的存储和加载。通常在推理过程中&#xff0c;会将权重参数存储在外部DDR或片上S…

c++简单实现avl树

文章目录 AVL树节点类节点类的构造函数 AVLinsert()插入RotateL(左单旋)RotateR(右单旋)RotateLR(右双旋)RotateRL(左双旋) Find(查找)IsBalance(检查是否是avl树) AVL树 AVL树:又名高度平衡树&#xff0c;在二叉搜索树的基础上加上了一个条件&#xff0c;条件是左右子树高度差…

vulhub中GitLab 远程命令执行漏洞复现(CVE-2021-22205)

GitLab是一款Ruby开发的Git项目管理平台。在11.9以后的GitLab中&#xff0c;因为使用了图片处理工具ExifTool而受到漏洞CVE-2021-22204的影响&#xff0c;攻击者可以通过一个未授权的接口上传一张恶意构造的图片&#xff0c;进而在GitLab服务器上执行任意命令。 环境启动后&am…

FFmpeg查看所有支持的编码/解码器/封装/解封装/媒体格式/滤镜

查看所有支持的编码器与解码器 ffmpeg -codecs 只查看所有编码器: ffmpeg -encoders 只查看所有解码器: ffmpeg -decoders 只查看H264编码器: ffmpeg -h encoderh264 只查看H264解码器: ffmpeg -h decoderh264 查看所有支持的封装: ffmpeg -muxers 查看所有支持的解封装…

【开源鸿蒙】为QEMU RISC-V虚拟平台构建OpenHarmony轻量系统

文章目录 一、背景介绍二、准备OpenHarmony源代码三、准备hb命令3.1 安装hb命令3.2 检查hb命令 四、编译RISC-V架构的OpenHarmony轻量系统4.1 设置hb构建目标4.2 启动hb构建过程 五、问题解决5.1 hb set 报错问题解决 六、参考链接 开源鸿蒙坚果派&#xff0c;学习鸿蒙一起来&a…

【每日算法】常见AIGC模型; 刷题:力扣单调栈

上期文章 【每日算法】理论&#xff1a;生成模型基础&#xff1b; 刷题&#xff1a;力扣单调栈 文章目录 上期文章一、上期问题二、理论问题1、stable diffusion模型的网络架构2、T5的网络架构&#xff08;Text-To-Text Transfer Transformer模型&#xff09;3、SDXL模型4、DA…

Git全套教程一套精通git.跟学黑马笔记

Git全套教程一套精通git.跟学黑马笔记 文章目录 Git全套教程一套精通git.跟学黑马笔记1.版本管理工具概念2. 版本管理工具介绍2.1版本管理发展简史(维基百科)2.1.1 SVN(SubVersion)2.1.2 Git 3. Git 发展简史4. Git 的安装4.1 git 的下载4.2 安装4.3 基本配置4.4 为常用指令配置…

【jeecgboot】微服务实战LISM

目录 一、服务解决方案-Spring Cloud Alibaba1.1选用原因&#xff08;基于Spring Cloud Alibaba的试用场景&#xff09;1.2 核心组件使用前期规划 部署 nacos部署 mino使用JavaFreemarker模板引擎&#xff0c;根据XML模板文件生成Word文档使用JavaFlowable 工作流引擎前端 -vue…