回溯算法总结
首先回溯算法本身还是一个纯暴力的算法,只是回溯过程可能比较抽象,导致大家总是感觉看到的相关题目做的不是很顺畅,回溯算法一般来说解决的题目有以下几类:
组合问题:lq77、lq17、lq39、lq40、lq216、
切割问题:lq131、lq93、
子集问题:lq78、lq90、
排列问题:lq46、lq47、
棋盘问题:lq51、lq37、
其他类:lq491、lq332、
在回溯算法中,所有的问题都可以抽象为一个树形结构

回溯算法四部曲:
1、递归函数、参数、返回值
2、确定终止条件
3、单层递归逻辑
4、剪枝操作(一般在for中i的遍历范围做控制)
回溯算法模板:
//回溯算法模板
public class HuiSu {LinkedList<Integer> path = new LinkedList<>();List<List<Integer>> result = new ArrayList<>();//功能函数,调用backtracking()public List<List<Integer>> main(String[] args) {backtracking(1);return result;}public void backtracking(int startindex){
// if(终止条件){
// 1、收集结果
// return;
// }
// for(int i=startindex;i<k;i++){
// 1、处理节点
// 2、backtracking(i+1);
// 3、回溯,撤销结果
// }}
}
下面我们来看具体的题目:
组合问题:
lq77:组合问题
给定两个整数 n 和 k,返回范围 [1, n] 中所有可能的 k 个数的组合。
你可以按 任何顺序 返回答案。
示例
输入:n = 4, k = 2 输出: [ [2,4], [3,4], [2,3], [1,2], [1,3], [1,4], ]
答案:我们按照回溯算法的模板,即可完成这道题目的代码部分。
class Solution {LinkedList<Integer> path = new LinkedList<>();List<List<Integer>> result = new ArrayList<>();public List<List<Integer>> combine(int n, int k) {backtracking(n,k,1);return result;}public void backtracking(int n,int k,int startindex){if(path.size() == k){result.add(new ArrayList<>(path));return;}for(int i = startindex; i<=n-(k-path.size())+1; i++){path.add(i);backtracking(n,k,i+1);path.removeLast();} }
}
lq216:组合总和III
找出所有相加之和为 n 的 k 个数的组合,且满足下列条件:
只使用数字1到9
每个数字 最多使用一次
返回 所有可能的有效组合的列表 。该列表不能包含相同的组合两次,组合可以以任何顺序返回。
示例:
输入:k = 3, n = 7 输出: [[1,2,4]] 解释: 1 + 2 + 4 = 7 没有其他符合的组合了。
答案:
class Solution {LinkedList<Integer> path = new LinkedList<>();List<List<Integer>> result = new ArrayList<>();public List<List<Integer>> combinationSum3(int k, int n) {backtracking(0,k,n,1);return result;}public void backtracking(int targetsum,int k,int n,int startindex){if(targetsum>n){return;}if(path.size()==k){if(targetsum==n){result.add(new ArrayList<>(path));return;}}for(int i=startindex;i<=9-(k-path.size())+1;i++){targetsum = targetsum+i;path.add(i);backtracking(targetsum,k,n,i+1);targetsum = targetsum-i;path.removeLast();}}
}
lq17:电话号码的字母组合
给定一个仅包含数字 2-9 的字符串,返回所有它能表示的字母组合。答案可以按 任意顺序 返回。
给出数字到字母的映射如下(与电话按键相同)。注意 1 不对应任何字母。

示例:
输入:digits = "23" 输出:["ad","ae","af","bd","be","bf","cd","ce","cf"]
注解:这道题目和前面两道题目有区别,前面两道题目是在一个集合中选取字符进行组合,这道题目中是在两个集合中分别选取,所以单层遍历时候不用startindex来控制,而需要转化为每个数字代表的字符个数来控制。
答案:
class Solution {StringBuilder path = new StringBuilder();List<String> result = new ArrayList<>();//初始对应所有的数字,为了直接对应2-9,新增了两个无效的字符串""String[] numString = {"", "", "abc", "def", "ghi", "jkl", "mno", "pqrs", "tuv", "wxyz"};public List<String> letterCombinations(String digits) {if (digits == null || digits.length() == 0) {return result;}backtracking(digits,0);return result;}public void backtracking(String digits,int num){if(num == digits.length()){result.add(path.toString());return;}String str = numString[digits.charAt(num) - '0'];for(int i=0;i<str.length();i++){path.append(str.charAt(i));backtracking(digits,num+1);path.deleteCharAt(path.length() - 1);}}
}
lq39:组合总和
给你一个 无重复元素 的整数数组 candidates 和一个目标整数 target ,找出 candidates 中可以使数字和为目标数 target 的 所有 不同组合 ,并以列表形式返回。你可以按 任意顺序 返回这些组合。
candidates 中的 同一个 数字可以 无限制重复被选取 。如果至少一个数字的被选数量不同,则两种组合是不同的。
对于给定的输入,保证和为 target 的不同组合数少于 150 个。
示例:
输入:candidates = [2,3,6,7], target = 7
输出:[[2,2,3],[7]]
解释:
2 和 3 可以形成一组候选,2 + 2 + 3 = 7 。注意 2 可以使用多次。
7 也是一个候选, 7 = 7 。
仅有这两种组合。
分析:此题目要进行剪枝操作,首先在sum+当前值之后大于target时,应该直接剪枝,其次,此题单层遍历时,当前值是可以重复的,但不代表不需要startindex,只是startindex在调用时不需要+1操作,因为如果没有startindex,就会造成重复。
//lq39.组合总和
class Solution {LinkedList<Integer> path = new LinkedList<>();List<List<Integer>> result = new ArrayList<>();public List<List<Integer>> combinationSum(int[] candidates, int target) {Arrays.sort(candidates); // 先进行排序backtracking(candidates,target,0,0);return result;}public void backtracking(int[] candidates, int target, int sum, int startindex){if(sum==target){result.add(new ArrayList<>(path));return;}for(int i = startindex;i<candidates.length;i++){if (sum + candidates[i] > target) break;sum=sum+candidates[i];path.add(candidates[i]);backtracking(candidates,target,sum,i);sum=sum-candidates[i];path.removeLast();}}
}
lq40:组合总和II
给定一个候选人编号的集合 candidates 和一个目标数 target ,找出 candidates 中所有可以使数字和为 target 的组合。
candidates 中的每个数字在每个组合中只能使用 一次 。
注意:解集不能包含重复的组合。
示例:
输入: candidates = [10,1,2,7,6,1,5], target = 8,
输出:
[
[1,1,6],
[1,2,5],
[1,7],
[2,6]
]
分析:此题中和其他题目不同的是需要判断如果两个数字相同的情况如何剪枝,此时需要用一个boolean[] used来标志此位是否遍历过,然后进行剪枝。此时剪枝时要注意used[i-1]==flase而不是true,因为我们此处想剪的是树形结构的一整个分支,如果是true的话是第一个树枝的下一层。
答案:
//lq40.组合总和II
class zuheZHII{LinkedList<Integer> path = new LinkedList<>();List<List<Integer>> result = new ArrayList<>();boolean[] used;public List<List<Integer>> combinationSum2(int[] candidates, int target) {used = new boolean[candidates.length];Arrays.fill(used, false);Arrays.sort(candidates);backtracking(candidates,target,0,0);return result;}public void backtracking(int[] candidates, int target,int sum, int startindex){if(sum == target){result.add(new ArrayList(path));return;}for(int i = startindex;i<candidates.length;i++){if((sum+candidates[i])>target){break;}if(i>0 && (candidates[i]==candidates[i-1]) && (used[i-1]==false)){continue;}used[i] = true;sum = sum+candidates[i];path.add(candidates[i]);backtracking(candidates,target,sum,i+1);sum = sum-candidates[i];used[i] = false;path.removeLast();}}public static void main(String[] args) {zuheZHII z = new zuheZHII();int[] candidates = {10,1,2,7,6,1,5};List<List<Integer>> res = z.combinationSum2(candidates,8);System.out.println(res);}
}
lq131:分割回文串
给你一个字符串 s,请你将 s 分割成一些子串,使每个子串都是 回文串 。返回 s 所有可能的分割方案。
回文串 是正着读和反着读都一样的字符串。
示例:
输入:s = "aab" 输出:[["a","a","b"],["aa","b"]]
分析:此题比较重要的是如何确定终止条件?当遍历标志位startindex>s.length()时,说明得到一个分割方案了,此时就可以回收path了,这个点和之前的组合问题不同,需要注意,然后就是判断回文串的时候需要注意一些,其他问题都和模板一致。
答案:
//lq131.分割回文串
class huiwenchaun {List<List<String>> lists = new ArrayList<>();Deque<String> deque = new LinkedList<>();public List<List<String>> partition(String s) {backTracking(s, 0);return lists;}private void backTracking(String s, int startIndex) {//如果起始位置大于s的大小,说明找到了一组分割方案if (startIndex >= s.length()) {lists.add(new ArrayList(deque));return;}for (int i = startIndex; i < s.length(); i++) {//如果是回文子串,则记录if (isPalindrome(s, startIndex, i)) {String str = s.substring(startIndex, i + 1);deque.addLast(str);} else {continue;}//起始位置后移,保证不重复backTracking(s, i + 1);deque.removeLast();}}//判断是否是回文串private boolean isPalindrome(String s, int startIndex, int end) {for (int i = startIndex, j = end; i < j; i++, j--) {if (s.charAt(i) != s.charAt(j)) {return false;}}return true;}public static void main(String[] args) {huiwenchaun h = new huiwenchaun();String s = "aab";List<List<String>> str = h.partition(s);System.out.println(str);}
}
lq93:复原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 地址。
给定一个只包含数字的字符串 s ,用以表示一个 IP 地址,返回所有可能的有效 IP 地址,这些地址可以通过在 s 中插入 '.' 来形成。你 不能 重新排序或删除 s 中的任何数字。你可以按 任何 顺序返回答案。
示例:
输入:s = "25525511135" 输出:["255.255.11.135","255.255.111.35"]
分析:此题相对比较难,因为需要这样想,切分IP地址的时候要加".",所以终止条件就是"."的个数,并且需要判断是否符合IP地址的规定。
答案:
class Solution {List<String> str = new ArrayList<>();public List<String> restoreIpAddresses(String s) {if(s.length()>12) return str;backTracking(s,0,0);return str;}// startIndex: 搜索的起始位置, pointNum:添加逗点的数量private void backTracking(String s, int startIndex, int pointnum) {if(pointnum == 3){// 逗点数量为3时,分隔结束// 判断第四段⼦字符串是否合法,如果合法就放进result中if(isPalindrome(s,startIndex,s.length()-1)){str.add(s);}return;}for(int i = startIndex;i<s.length();i++){if(isPalindrome(s,startIndex,i)){s = s.substring(0,i+1)+"."+s.substring(i+1);//在str的后⾯插⼊⼀个逗点pointnum++;backTracking(s,i+2,pointnum);// 插⼊逗点之后下⼀个⼦串的起始位置为i+2pointnum--;s = s.substring(0, i + 1) + s.substring(i + 2);// 回溯删掉逗点}else {break;}}}// 判断字符串s在左闭⼜闭区间[start, end]所组成的数字是否合法public boolean isPalindrome(String s,int start,int end){if (start > end) {return false;}if (s.charAt(start) == '0' && start != end) { // 0开头的数字不合法return false;}int num = 0;for (int i = start; i <= end; i++) {if (s.charAt(i) > '9' || s.charAt(i) < '0') { // 遇到⾮数字字符不合法return false;}num = num * 10 + (s.charAt(i) - '0');if (num > 255) { // 如果⼤于255了不合法return false;}}return true;}
}
lq78:子集
给你一个整数数组 nums ,数组中的元素 互不相同 。返回该数组所有可能的子集(幂集)。
解集 不能 包含重复的子集。你可以按 任意顺序 返回解集。
示例:
输入:nums = [1,2,3] 输出:[[],[1],[2],[1,2],[3],[1,3],[2,3],[1,2,3]]
分析:此题属于子集问题,相对于组合问题不同的是收集结果的时间不同,组合问题收集的是所有的叶子节点,而子集问题是收集所有的节点。
答案:
//lq78.子集
class ZJ {List<List<Integer>> result = new ArrayList<>();LinkedList<Integer> path = new LinkedList<>();public List<List<Integer>> subsets(int[] nums) {backtracking(nums,0);return result;}public void backtracking(int[] nums,int startindex){result.add(new ArrayList<>(path));if(startindex>=nums.length){return;}for(int i=startindex;i<nums.length;i++){path.add(nums[i]);backtracking(nums,i+1);path.removeLast();}}public static void main(String[] args) {ZJ z = new ZJ();int[] candidates = {1,2,3};List<List<Integer>> res = z.subsets(candidates);System.out.println(res);}
}
lq90:子集II
给你一个整数数组 nums ,其中可能包含重复元素,请你返回该数组所有可能的子集(幂集)。
解集 不能 包含重复的子集。返回的解集中,子集可以按 任意顺序 排列。
示例:
输入:nums = [1,2,2] 输出:[[],[1],[1,2],[1,2,2],[2],[2,2]]
分析:此题和lq40.组合总和II比较类似,主要难点在于剪枝,剪枝过程和lq40.组合总完全一致
答案:
//lq90.子集II
class ZJII {LinkedList<Integer> path = new LinkedList<>();List<List<Integer>> result = new ArrayList<>();boolean[] used;public List<List<Integer>> subsetsWithDup(int[] nums) {used = new boolean[nums.length];Arrays.fill(used,false);Arrays.sort(nums);backtracking(nums,0);return result;}public void backtracking(int[] nums,int startindex){result.add(new ArrayList<>(path));if(startindex >= nums.length){return;}for(int i=startindex;i<nums.length;i++){if(i>0 && nums[i]==nums[i-1] && used[i-1]==false){continue;}used[i]=true;path.add(nums[i]);backtracking(nums,i+1);used[i]=false;path.removeLast();}}public static void main(String[] args) {ZJII z = new ZJII();int[] candidates = {1,2,2};List<List<Integer>> res = z.subsetsWithDup(candidates);System.out.println(res);}
}
【重要】lq491:递增子序列
给你一个整数数组 nums ,找出并返回所有该数组中不同的递增子序列,递增子序列中 至少有两个元素 。你可以按 任意顺序 返回答案。
数组中可能含有重复元素,如出现两个整数相等,也可以视作递增序列的一种特殊情况。
示例:
输入:nums = [4,6,7,7] 输出:[[4,6],[4,6,7],[4,6,7,7],[4,7],[4,7,7],[6,7],[6,7,7],[7,7]]
分析:
此题比较重要,同样也比较困难一些,此题的难度在于剪枝和判断递增,此处的剪枝本身还是去重,和前面的题目类似,只是前面的组合或者其他题目可以通过对数组排序,保证相同的数连在一起,所以可以通过boolean[]数组来记录,此题通过简单的数组下标并不能控制,所以需要借助HashMap来控制是否重复的问题。此题在回溯算法中相对比较全面。
还有一个重要的点就是终止条件后的return;并不是每道题目的终止条件后面都要return,因为此题目的终止条件并不是不在遍历,只有当收集的是叶子节点为终止条件时才需要加return,其他时候不需要,因为终止条件只是要收集结果,并不是遍历结束。
//lq491.递增子序列
class DZZXL{LinkedList<Integer> path = new LinkedList<>();List<List<Integer>> result = new ArrayList<>();public List<List<Integer>> findSubsequences(int[] nums) {backtracking(nums,0);return result;}public void backtracking(int[] nums,int startindex){if(path.size()>=2){result.add(new ArrayList<>(path));}HashMap<Integer,Integer> map = new HashMap<>();for(int i=startindex;i<nums.length;i++){if(!path.isEmpty() && nums[i]< path.getLast()){continue;}if(map.containsKey(nums[i])){continue;}map.put(nums[i],1);path.add(nums[i]);backtracking(nums,i+1);path.removeLast();}}public static void main(String[] args) {DZZXL z = new DZZXL();int[] candidates = {4,6,7,7};List<List<Integer>> res = z.findSubsequences(candidates);System.out.println(res);}
}
lq46:全排列
给定一个不含重复数字的数组 nums ,返回其 所有可能的全排列 。你可以 按任意顺序 返回答案。
示例:
输入:nums = [1,2,3] 输出:[[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2],[3,2,1]]
答案:
class Solution {LinkedList<Integer> path = new LinkedList<>();List<List<Integer>> result = new ArrayList<>();boolean[] used;public List<List<Integer>> permute(int[] nums) {used = new boolean[nums.length];Arrays.fill(used,false);backtracking(nums,used);return result;}public void backtracking(int[] nums,boolean[] used){if(path.size()==nums.length){result.add(new ArrayList<>(path));return;}for(int i=0;i<nums.length;i++){if(used[i]==true){continue;}used[i] = true;path.add(nums[i]);backtracking(nums,used);path.removeLast();used[i] =false;}}
}
lq47.全排列II
给定一个可包含重复数字的序列 nums ,按任意顺序 返回所有不重复的全排列。
示例:
输入:nums = [1,1,2] 输出: [[1,1,2], [1,2,1], [2,1,1]]
分析:
此题目主要还是去重,和前面lq40.组合总和的方法基本一致,需要你注意的就是判断,当used[i]==true时,需要跳过此次遍历,否则会造成重复。其他的都是基本操作。
答案:
//lq47.全排列II
class QPLII{LinkedList<Integer> path = new LinkedList<>();List<List<Integer>> result = new ArrayList<>();boolean[] used;public List<List<Integer>> permuteUnique(int[] nums) {used = new boolean[nums.length];Arrays.fill(used,false);Arrays.sort(nums);backtracking(nums,used);return result;}public void backtracking(int[] nums,boolean[] used){if(path.size()==nums.length){result.add(new ArrayList<>(path));return;}for(int i=0;i<nums.length;i++){if(i>0 && nums[i]==nums[i-1] && used[i-1]==false){continue;}if(used[i]==true){continue;}used[i] = true;path.add(nums[i]);backtracking(nums,used);used[i] = false;path.removeLast();}}public static void main(String[] args) {QPLII q = new QPLII();int[] candidates = {1,1,2};List<List<Integer>> res = q.permuteUnique(candidates);System.out.println(res);}
}
lq51:N皇后问题
按照国际象棋的规则,皇后可以攻击与之处在同一行或同一列或同一斜线上的棋子。
n 皇后问题 研究的是如何将 n 个皇后放置在 n×n 的棋盘上,并且使皇后彼此之间不能相互攻击。
给你一个整数 n ,返回所有不同的 n 皇后问题 的解决方案。
每一种解法包含一个不同的 n 皇后问题 的棋子放置方案,该方案中 'Q' 和 '.' 分别代表了皇后和空位。
示例:

输入:n = 4 输出:[[".Q..","...Q","Q...","..Q."],["..Q.","Q...","...Q",".Q.."]] 解释:如上图所示,4 皇后问题存在两个不同的解法。
分析:此题目是回溯算法中相对比较难的题目,主要原因是不知如何将问题转化为回溯算法来进行解决,我们可以通过以下树形结构图来分析此题目。

所以此题的树形结构深度就是棋盘的行数是,树形结构的宽度就是棋盘的宽度
在for(int col=0;col<n;col++)中遍历的就是在一行中,也就是树形结构的一层中遍历每一列的情况,在每一次递归时传入的参数row+1,就是遍历树形结构不同的层,也就是棋盘结构不同的行。
此题目还需要注意的一个点是,我们需要自己构建一个二维数组作为棋盘结构,然后还需要一个函数来判断当前棋盘是否符合条件。最重要的一点是,题目要求的返回值是一个二维数组,所以每一种成功的棋盘布局需要转换成一个一维数组,多个成功的棋盘构成最终答案,所以还需要一个函数将棋盘结构转换成一维数组。
答案:
//lq51.N皇后问题
class NQueen {List<List<String>> result = new ArrayList<>();public List<List<String>> solveNQueens(int n) {char[][] chessboard = new char[n][n];for (char[] c : chessboard) {Arrays.fill(c, '.');}backtracking(n,0,chessboard);return result;}public void backtracking(int n,int row,char[][] chessboard){if(row==n){List<String> res = tolist(chessboard);result.add(res);return;}for(int col=0;col<n;col++){if(is(chessboard,row,col,n)){chessboard[row][col] = 'Q';backtracking(n, row+1, chessboard);chessboard[row][col] = '.';}}}public List<String> tolist(char[][] chessboard){List<String> list = new ArrayList<>();for (char[] c : chessboard) {list.add(String.copyValueOf(c));}return list;}public boolean is(char[][] chessboard,int row,int col,int n){for (int i=0; i<row; ++i) { // 相当于剪枝if (chessboard[i][col] == 'Q') {return false;}}// 检查45度对角线for (int i=row-1, j=col-1; i>=0 && j>=0; i--, j--) {if (chessboard[i][j] == 'Q') {return false;}}// 检查135度对角线for (int i=row-1, j=col+1; i>=0 && j<=n-1; i--, j++) {if (chessboard[i][j] == 'Q') {return false;}}return true;}public static void main(String[] args) {int n = 4;NQueen nqueen = new NQueen();List<List<String>> res = nqueen.solveNQueens(n);System.out.println(res);}
}
相关文章:

回溯算法总结
首先回溯算法本身还是一个纯暴力的算法,只是回溯过程可能比较抽象,导致大家总是感觉看到的相关题目做的不是很顺畅,回溯算法一般来说解决的题目有以下几类:组合问题:lq77、lq17、lq39、lq40、lq216、切割问题ÿ…...

ccc-pytorch-基础操作(2)
文章目录1.类型判断isinstance2.Dimension实例3.Tensor常用操作4.索引和切片5.Tensor维度变换6.Broadcast自动扩展7.合并与分割8.基本运算9.统计属性10.高阶OP大伙都这么聪明,注释就只写最关键的咯1.类型判断isinstance 常见类型如下: a torch.randn(…...

独居老人一键式报警器
盾王居家养老一键式报警系统,居家养老一键式报警设备 ,一键通紧急呼救设备,一键通紧急呼救系统,一键通紧急呼救器 ,一键通紧急呼救终端,一键通紧急呼救主机终端产品简介: 老人呼叫系统主要应用于…...

软考案例分析题精选
试题一:阅读下列说明,回答问题1至问题4,将解答填入答题纸的对应栏内。某公司中标了一个软件开发项目,项目经理根据以往的经验估算了开发过程中各项任务需要的工期及预算成本,如下表所示:任务紧前任务工期PV…...

基于SpringBoot+vue的无偿献血后台管理系统
基于SpringBootvue的无偿献血后台管理系统 ✌全网粉丝20W,csdn特邀作者、博客专家、CSDN新星计划导师、java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ 🍅文末获取项目下载方式🍅 一、项目背…...

详解js在事件中,如何传递复杂数据类型(数组,对象,函数)
文章目录 前言一、何谓预编译,变量提升?二、复杂数据类型的传递 1.数组2.对象3.函数总结前言 在JavaScript这门编程语言学习中,如何传参,什么是变量提升,js代码预编译等等。要想成为一名优秀的js高手,这些内…...

高并发架构 第一章大型网站数据演化——核心解释与说明。大型网站技术架构——核心原理与案例分析
大型网站架构烟花发展历程1.1.1初始阶段的网站构架1.1.2应用服务和数据服务分离1.1.3使用缓存改善网络性能1.1.4使用应用服务器集群改善网站的并发处理能力1.1.5数据库读写分离1.1.6使用反向代理和cdn加速网站相应1.1.1初始阶段的网站构架 大型网站都是由小型网站一步步发展而…...
VPP接口INPUT节点运行数据
在设置virtio接口接收/发送队列函数的最后,更新接口的运行数据。 void virtio_vring_set_rx_queues (vlib_main_t *vm, virtio_if_t *vif) { ...vnet_hw_if_update_runtime_data (vnm, vif->hw_if_index); } void virtio_vring_set_tx_queues (vlib_main_t *vm,…...

RabbitMQ学习(九):延迟队列
一、延迟队列概念延时队列中,队列内部是有序的,最重要的特性就体现在它的延时属性上,延时队列中的元素是希望 在指定时间到了以后或之前取出和处理。简单来说,延时队列就是用来存放需要在指定时间内被处理的 元素的队列。其实延迟…...

TCP并发服务器(多进程与多线程)
欢迎关注博主 Mindtechnist 或加入【Linux C/C/Python社区】一起探讨和分享Linux C/C/Python/Shell编程、机器人技术、机器学习、机器视觉、嵌入式AI相关领域的知识和技术。 TCP并发服务器(多进程与多线程)1. 多进程并发服务器(1)…...
第1章 Memcached 教程
Memcached是一个自由开源的,高性能,分布式内存对象缓存系统。 Memcached是以LiveJournal旗下Danga Interactive公司的Brad Fitzpatric为首开发的一款软件。现在已成为mixi、hatena、Facebook、Vox、LiveJournal等众多服务中提高Web应用扩展性的重要因素…...

【2022.12.9】Lammps+Python 在计算g6(r)时遇到的问题
目录写在前面绘制g6( r )执行步骤【updated】如何检查图像的正确性:不是编程问题,而是数学问题的一个小bug废稿2则:写在前面 全部log: 【2022.11.16】LammpsPythonMATLAB在绘制维诺图时遇到的问题 绘制g6( r )执行步骤【updated…...

MySQL使用C语言连接
文章目录MySQL使用C语言连接引入库下载库文件在项目中使用库使用库连接数据库下发SQL请求获取查询结果MySQL使用C语言连接 引入库 要使用C语言连接MySQL,需要使用MySQL官网提供的库。 下载库文件 下载库文件 首先,进入MySQL官网,选择DEVEL…...

JavaScript随手笔记---比较两个数组差异
💌 所属专栏:【JavaScript随手笔记】 😀 作 者:我是夜阑的狗🐶 🚀 个人简介:一个正在努力学技术的CV工程师,专注基础和实战分享 ,欢迎咨询! &#…...

【C++修炼之路】21.红黑树封装map和set
每一个不曾起舞的日子都是对生命的辜负 红黑树封装map和set前言一.改良红黑树的数据域结构1.1 改良后的结点1.2 改良后的类二. 封装的set和map2.1 set.h2.2 map.h三. 迭代器3.1 迭代器封装3.2 const迭代器四.完整代码实现4.1 RBTree.h4.2 set.h4.3 map.h4.4 Test.cpp前言 上一节…...
下载ojdbc14.jar的10.2.0.1.0版本的包
一、首先要有ojdbc14.jar包 没有的可以去下载一个,我的是从这里下载的ojdbc14.jar下载_ojdbc14.jar最新版下载[驱动包软件]-下载之家, 就是无奈关注了一个公众号,有的就不用下了。 二、找到maven的本地仓库的地址 我的地址在这里D:\apach…...

关于欧拉角你需要知道几个点
基础理解,参照:https://www.cnblogs.com/Estranged-Tech/p/16903025.html 欧拉角、万向节死锁(锁死)理解 一、欧拉角理解 举例讲解 欧拉角用三次独立的绕确定的轴旋转角度来表示姿态。如下图所示 经过三次旋转,旋…...

git ssh配置
ssh配置 执行以下命令进行配置 git config --global user.name “这里换上你的用户名” git config --global user.email “这里换上你的邮箱” 执行以下命令生成秘钥: ssh-keygen -t rsa -C “这里换上你的邮箱” 执行命令后需要进行3次或4次确认。直接全部回车就…...

Linux进程概念(三)
环境变量与进程地址空间环境变量什么是环境变量常见环境变量环境变量相关命令环境变量的全局属性PWDmain函数的三个参数进程地址空间什么是进程地址空间进程地址空间,页表,内存的关系为什么存在进程地址空间环境变量 什么是环境变量 我们所有写的程序都…...

新手福利——x64逆向基础
一、x64程序的内存和通用寄存器 随着游戏行业的发展,x32位的程序已经很难满足一些新兴游戏的需求了,因为32位内存的最大值为0xFFFFFFFF,这个值看似足够,但是当游戏对资源需求非常大,那么真正可以分配的内存就显得捉襟…...
在rocky linux 9.5上在线安装 docker
前面是指南,后面是日志 sudo dnf config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo sudo dnf install docker-ce docker-ce-cli containerd.io -y docker version sudo systemctl start docker sudo systemctl status docker …...

无法与IP建立连接,未能下载VSCode服务器
如题,在远程连接服务器的时候突然遇到了这个提示。 查阅了一圈,发现是VSCode版本自动更新惹的祸!!! 在VSCode的帮助->关于这里发现前几天VSCode自动更新了,我的版本号变成了1.100.3 才导致了远程连接出…...
【算法训练营Day07】字符串part1
文章目录 反转字符串反转字符串II替换数字 反转字符串 题目链接:344. 反转字符串 双指针法,两个指针的元素直接调转即可 class Solution {public void reverseString(char[] s) {int head 0;int end s.length - 1;while(head < end) {char temp …...

在WSL2的Ubuntu镜像中安装Docker
Docker官网链接: https://docs.docker.com/engine/install/ubuntu/ 1、运行以下命令卸载所有冲突的软件包: for pkg in docker.io docker-doc docker-compose docker-compose-v2 podman-docker containerd runc; do sudo apt-get remove $pkg; done2、设置Docker…...
Element Plus 表单(el-form)中关于正整数输入的校验规则
目录 1 单个正整数输入1.1 模板1.2 校验规则 2 两个正整数输入(联动)2.1 模板2.2 校验规则2.3 CSS 1 单个正整数输入 1.1 模板 <el-formref"formRef":model"formData":rules"formRules"label-width"150px"…...
laravel8+vue3.0+element-plus搭建方法
创建 laravel8 项目 composer create-project --prefer-dist laravel/laravel laravel8 8.* 安装 laravel/ui composer require laravel/ui 修改 package.json 文件 "devDependencies": {"vue/compiler-sfc": "^3.0.7","axios": …...
现有的 Redis 分布式锁库(如 Redisson)提供了哪些便利?
现有的 Redis 分布式锁库(如 Redisson)相比于开发者自己基于 Redis 命令(如 SETNX, EXPIRE, DEL)手动实现分布式锁,提供了巨大的便利性和健壮性。主要体现在以下几个方面: 原子性保证 (Atomicity)ÿ…...
C++.OpenGL (20/64)混合(Blending)
混合(Blending) 透明效果核心原理 #mermaid-svg-SWG0UzVfJms7Sm3e {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-SWG0UzVfJms7Sm3e .error-icon{fill:#552222;}#mermaid-svg-SWG0UzVfJms7Sm3e .error-text{fill…...
掌握 HTTP 请求:理解 cURL GET 语法
cURL 是一个强大的命令行工具,用于发送 HTTP 请求和与 Web 服务器交互。在 Web 开发和测试中,cURL 经常用于发送 GET 请求来获取服务器资源。本文将详细介绍 cURL GET 请求的语法和使用方法。 一、cURL 基本概念 cURL 是 "Client URL" 的缩写…...

通过 Ansible 在 Windows 2022 上安装 IIS Web 服务器
拓扑结构 这是一个用于通过 Ansible 部署 IIS Web 服务器的实验室拓扑。 前提条件: 在被管理的节点上安装WinRm 准备一张自签名的证书 开放防火墙入站tcp 5985 5986端口 准备自签名证书 PS C:\Users\azureuser> $cert New-SelfSignedCertificate -DnsName &…...