文章目录

  • 代码随想录在B站的视频讲得比AcWing好
  • 模板题1:排列数字
  • 模板题2:n皇后
    • 方法一
    • 方法二
  • LeetCode 46. 全排列
  • LeetCode 47. 全排列 II (重复元素)
  • LeetCode 39. 组合总和
  • LeetCode 77. 组合
  • LeetCode 78. 子集
  • LeetCode 216. 组合总和 III
  • LeetCode 17. 电话号码的字母组合
  • LeetCode 131. 分割回文串
  • LeetCode 93. 复原 IP 地址(还没太学懂)
  • LeetCode 90. 子集 II
  • LeetCode 491. 递增子序列

代码随想录在B站的视频讲得比AcWing好

模板题1:排列数字

// 按行单个搜索
#include <iostream>
using namespace std;
const int N = 7;
int n;
int path[N]; //保存路径,定义一个数组path[N] 来保存当前的路径/模拟DFS的过程,当这个数组数字填满的时候,就把当前的排列数字输出出来
bool st[N]; //用于记录该店是否来过  反正dfs重新进入void dfs(int u) { //u表示层数,u从0开始if (u == n) { //当数填满n位数时  输出n位数 并且换行for (int i = 0; i < n; i ++) {  printf("%d ", path[i]);} puts("");return ;}for (int i = 1; i <= n; i ++) { if (!st[i]) { //如果这个位置空的话(没有来过)path[u] = i;// u从0开始st[i] = true; //填数的时候记录一下dfs(u + 1); //访问下一层,u变成1st[i] = false; //回溯的时候 恢复现场[]}}
}int main () {cin >> n;dfs(0); //这个题直接遍历return 0;
}

模板题2:n皇后

方法一

#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;const int N = 10;char g[N][N];
int n;
bool col[N], dg[N], udg[N]; // 用于标记每一列、正对角线、负对角线是否占用// u 表示第u行
void dfs(int u)
{ if(u == n){for(int i = 0; i < n; i++) puts(g[i]);// puts输出二维数组 输出每一行如何就会自动换行puts(""); return ;  }   // u表示行,从0开始计算,i表示第i列 // 按行枚举 因为每一行都需要放皇后 相当于剪枝了// 剪枝(提前判断当前方案已经错误,不再继续往下搜索,提高算法效率) // 判断皇后能否放在这格for(int i = 0; i < n; i++){// u表示行,i表示列,u+i表示正对角线的编号,i-u+n表示负对角线编号 // col[i]=false:第u层的第i列没有皇后// dg[u+i]=false:u是外层递归,i是内层循环,i从0开始试,第u层的第u+i列没有皇后if(!col[i] && !dg[u+i] && !udg[i-u+n]){g[u][i] = 'Q'; // 都不冲突的话,就把一个皇后放到这里 col[i] = dg[u+i] = udg[i-u+n] = true; // 表示该列、对角线被占用 dfs(u+1); //下一行g[u][i] = '.'; col[i] = dg[u+i] = udg[i-u+n] = false; // }}
}int main()
{scanf("%d", &n);// 初始化gfor(int i = 0; i < n; i++) for(int j = 0; j < n; j++)g[i][j] = '.';dfs(0); return 0;
}

方法二

#include <iostream>
using namespace std;
const int N = 20;//对角线元素 2n-1 取20防止越界
int n;
char g[N][N]; //存储图
bool row[N],col[N], dg[N], udg[N]; //udg 副对角线 /
//英语单词 column 列   diagonal 主角线 \
//row 行void dfs (int x,int y,int s) {  //xy为坐标 (x,y) s为 n皇后放置个数if (y == n) { //当x走到行末尾的时候  y = 0;    //转到下一行的第一个x++;}if (x == n) { //走到最后一行 且n皇后都放好的时候if (s == n) { // 如果找到方案的话for (int i = 0; i < n; i ++) {puts(g[i]);//puts输出二维数组 输出每一行如何就会自动换行 }//puts遍历字符串这个语法不懂看下puts("");}return; //返回调用函数进行执行}dfs(x, y + 1, s);//不放皇后  并且访问右节点// 判断皇后能否放在这格if (!row[x] && !col[y] && !dg[x + y] && !udg[x - y + n]) {g[x][y] = 'Q';//放皇后 然后把row[x] = col[y] = dg[x + y] = udg[x - y + n] = true;dfs(x , y + 1, s + 1);//放置皇后,找下一层的//回溯的时候 记得恢复现场 ↓ row[x] = col[y] = dg[x + y] = udg[x - y + n] = false; g[x][y] = '.';}
}int main () {cin >> n;for (int i = 0; i < n;i ++) {for (int j = 0; j < n; j ++) {g[i][j] = '.'; //初始化全部空格子}}dfs(0,0,0); //从第一行开始找return 0;
}

LeetCode 46. 全排列

class Solution {public:vector<vector<int>> result; // 存放路径集合vector<int> path; // 存放单个路径void backtracking (vector<int>& nums, vector<bool>& used) {// 此时说明找到了一组if (path.size() == nums.size()) {result.push_back(path);return;}//当路径大小没装满时for (int i = 0; i < nums.size(); i++) {if (used[i] == true) continue; // path里已经收录的元素,直接跳过used[i] = true; // 把i位置的元素做标记path.push_back(nums[i]); //把i位置的元素加入路径中backtracking(nums, used); // 对剩下的元素进行重排path.pop_back(); // 弹出当前元素,换另一个元素used[i] = false; // 回溯}}vector<vector<int>> permute(vector<int>& nums) {result.clear();path.clear();vector<bool> used(nums.size(), false);backtracking(nums, used);return result;}
};作者:carlsun-2
链接:https://leetcode.cn/problems/permutations/solution/dai-ma-sui-xiang-lu-dai-ni-xue-tou-hui-s-mfrp/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

LeetCode 47. 全排列 II (重复元素)

class Solution {private:vector<vector<int>> result;vector<int> path;void backtracking(vector<int>& candidates, int target, int sum, int startIndex) {if (sum == target) {result.push_back(path);return;}// 如果 sum + candidates[i] > target 就终止遍历for (int i = startIndex; i < candidates.size() && sum + candidates[i] <= target; i++) {sum += candidates[i];path.push_back(candidates[i]);backtracking(candidates, target, sum, i);sum -= candidates[i];path.pop_back();}}
public:vector<vector<int>> combinationSum(vector<int>& candidates, int target) {result.clear();path.clear();sort(candidates.begin(), candidates.end()); // 需要排序backtracking(candidates, target, 0, 0);return result;}
};作者:carlsun-2
链接:https://leetcode.cn/problems/combination-sum/solution/dai-ma-sui-xiang-lu-dai-ni-xue-tou-hui-s-7tum/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

LeetCode 39. 组合总和

class Solution {private:vector<vector<int>> result;vector<int> path;void backtracking(vector<int>& candidates, int target, int sum, int startIndex) {if (sum == target) {result.push_back(path);return;}// 如果 sum + candidates[i] > target 就终止遍历for (int i = startIndex; i < candidates.size() && sum + candidates[i] <= target; i++) {sum += candidates[i];path.push_back(candidates[i]);backtracking(candidates, target, sum, i);sum -= candidates[i];path.pop_back();}}
public:vector<vector<int>> combinationSum(vector<int>& candidates, int target) {result.clear();path.clear();sort(candidates.begin(), candidates.end()); // 需要排序backtracking(candidates, target, 0, 0);return result;}
};

LeetCode 77. 组合

class Solution {private:vector<vector<int>> result; // 存放符合条件结果的集合vector<int> path; // 用来存放符合条件结果//startIndex 避免组合重复选取元素(2,1)和(1,2)重复,标记搜索起始位置void backtracking(int n, int k, int startIndex) {if (path.size() == k) { // 路径元素满足要求时候就可以往result里存储该路径result.push_back(path);return; // 返回 递归出口}// 每次从startIndex开始添加新元素//for (int i = startIndex; i <= n; i++) {for (int i = startIndex; i <= n - (k - path.size()) + 1; i++) { // 优化的地方,剪枝,// (k - path.size())是还需要选取元素的个数,// n - (k - path.size()) + 1是最后能选取的位置,超过了就不满足选取K个元素的条件了path.push_back(i); // 处理节点,从i开始添加 backtracking(n, k, i + 1); // 递归path.pop_back(); // 回溯,撤销处理的节点,i++,重新进入for循环}}
public:vector<vector<int>> combine(int n, int k) {result.clear(); // 可以不写path.clear();   // 可以不写backtracking(n, k, 1);return result;}
};

LeetCode 78. 子集

class Solution {private:vector<vector<int>> result;vector<int> path;void backtracking(vector<int>& nums, int startIndex) {result.push_back(path); // 收集子集,要放在终止添加的上面,否则会漏掉自己if (startIndex >= nums.size()) { // 终止条件可以不加return;}for (int i = startIndex; i < nums.size(); i++) {path.push_back(nums[i]);backtracking(nums, i + 1);path.pop_back();}}
public:vector<vector<int>> subsets(vector<int>& nums) {result.clear();path.clear();backtracking(nums, 0);return result;}
};作者:carlsun-2
链接:https://leetcode.cn/problems/subsets/solution/dai-ma-sui-xiang-lu-78-zi-ji-hui-su-sou-6yfk6/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

LeetCode 216. 组合总和 III

class Solution {private:vector<vector<int>> result; // 存放结果集vector<int> path; // 符合条件的结果void backtracking(int targetSum, int k, int sum, int startIndex) {if (sum > targetSum) { // 剪枝操作return; // 如果path.size() == k 但sum != targetSum 直接返回}if (path.size() == k) {if (sum == targetSum) result.push_back(path);return;}for (int i = startIndex; i <= 9 - (k - path.size()) + 1; i++) { // 剪枝sum += i; // 处理path.push_back(i); // 处理backtracking(targetSum, k, sum, i + 1); // 注意i+1调整startIndexsum -= i; // 回溯path.pop_back(); // 回溯}}public:vector<vector<int>> combinationSum3(int k, int n) {result.clear(); // 可以不加path.clear();   // 可以不加backtracking(n, k, 0, 1);return result;}
};作者:carlsun-2
链接:https://leetcode.cn/problems/combination-sum-iii/solution/dai-ma-sui-xiang-lu-dai-ni-xue-tou-hui-s-petp/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

LeetCode 17. 电话号码的字母组合

class Solution {private:const string letterMap[10] = {"", // 0"", // 1"abc", // 2"def", // 3"ghi", // 4"jkl", // 5"mno", // 6"pqrs", // 7"tuv", // 8"wxyz", // 9};
public:vector<string> result;string s;void backtracking(const string& digits, int index) {if (index == digits.size()) {result.push_back(s);return;}int digit = digits[index] - '0';        // 将index指向的数字转为intstring letters = letterMap[digit];      // 取数字对应的字符集for (int i = 0; i < letters.size(); i++) {s.push_back(letters[i]);            // 处理backtracking(digits, index + 1);    // 递归,注意index+1,一下层要处理下一个数字了s.pop_back();                       // 回溯}}vector<string> letterCombinations(string digits) {s.clear();result.clear();if (digits.size() == 0) {return result;}backtracking(digits, 0);return result;}
};作者:carlsun-2
链接:https://leetcode.cn/problems/letter-combinations-of-a-phone-number/solution/dai-ma-sui-xiang-lu-17-dian-hua-hao-ma-d-ya2x/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

LeetCode 131. 分割回文串

class Solution {private:vector<vector<string>> result;vector<string> path; // 放已经回文的子串void backtracking (const string& s, int startIndex) {// 如果起始位置已经大于s的大小,说明已经找到了一组分割方案了if (startIndex >= s.size()) {result.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); // 寻找i+1为起始位置的子串path.pop_back(); // 回溯过程,弹出本次已经填在的子串}}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;}
public:vector<vector<string>> partition(string s) {result.clear();path.clear();backtracking(s, 0);return result;}
};作者:carlsun-2
链接:https://leetcode.cn/problems/palindrome-partitioning/solution/131-fen-ge-hui-wen-chuan-hui-su-sou-suo-yp2jq/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

LeetCode 93. 复原 IP 地址(还没太学懂)

class Solution {private:vector<string> result;// 记录结果// startIndex: 搜索的起始位置,pointNum:添加逗点的数量void backtracking(string& s, int startIndex, int pointNum) {if (pointNum == 3) { // 逗点数量为3时,分隔结束// 判断第四段子字符串是否合法,如果合法就放进result中if (isValid(s, startIndex, s.size() - 1)) {result.push_back(s);}return;}for (int i = startIndex; i < s.size(); i++) {if (isValid(s, startIndex, i)) { // 判断 [startIndex,i] 这个区间的子串是否合法s.insert(s.begin() + i + 1 , '.');  // 在i的后面插入一个逗点pointNum++;backtracking(s, i + 2, pointNum);   // 插入逗点之后下一个子串的起始位置为i+2pointNum--;                         // 回溯s.erase(s.begin() + i + 1);         // 回溯删掉逗点} else break; // 不合法,直接结束本层循环}}// 判断字符串s在左闭又闭区间[start, end]所组成的数字是否合法bool isValid(const string& s, int start, int end) {if (start > end) {return false;}if (s[start] == '0' && start != end) { // 0开头的数字不合法return false;}int num = 0;for (int i = start; i <= end; i++) {if (s[i] > '9' || s[i] < '0') { // 遇到非数字字符不合法return false;}num = num * 10 + (s[i] - '0');if (num > 255) { // 如果大于255了不合法return false;}}return true;}
public:vector<string> restoreIpAddresses(string s) {result.clear();if (s.size() > 12) return result; // 算是剪枝了backtracking(s, 0, 0);return result;}
};作者:carlsun-2
链接:https://leetcode.cn/problems/restore-ip-addresses/solution/dai-ma-sui-xiang-lu-93-fu-yuan-ip-di-zhi-pzjo/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

LeetCode 90. 子集 II

class Solution {private:vector<vector<int>> result;vector<int> path;void backtracking(vector<int>& nums, int startIndex, vector<bool>& used) {result.push_back(path);for (int i = startIndex; i < nums.size(); i++) {// used[i - 1] == true,说明同一树支candidates[i - 1]使用过// used[i - 1] == false,说明同一树层candidates[i - 1]使用过// 而我们要对同一树层使用过的元素进行跳过if (i > 0 && nums[i] == nums[i - 1] && used[i - 1] == false) {continue;}path.push_back(nums[i]);used[i] = true;backtracking(nums, i + 1, used);used[i] = false;path.pop_back();}}public:vector<vector<int>> subsetsWithDup(vector<int>& nums) {result.clear();path.clear();vector<bool> used(nums.size(), false);sort(nums.begin(), nums.end()); // 去重需要排序backtracking(nums, 0, used);return result;}
};作者:carlsun-2
链接:https://leetcode.cn/problems/subsets-ii/solution/90-zi-ji-iiche-di-li-jie-zi-ji-wen-ti-ru-djmf/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

LeetCode 491. 递增子序列

class Solution {private:vector<vector<int>> result;vector<int> path;void backtracking(vector<int>& nums, int startIndex) {if (path.size() > 1) {result.push_back(path);// 注意这里不要加return,要取树上的节点}unordered_set<int> uset; // 使用set对本层元素进行去重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();//uset不回溯,因为每次回溯都会定义一个新的set,这是与其他题目区别的地方}}
public:vector<vector<int>> findSubsequences(vector<int>& nums) {result.clear();path.clear();backtracking(nums, 0);return result;}
};

【AcWing19】【LeetCode】DFS - 46/47/39/77/78/216/17/131/93/90/491相关推荐

  1. 【一天一道Leetcode】基本计算器的延伸问题

    本篇推文共计2000个字,阅读时间约3分钟. 01 题目描述 题目描述: 给你一个字符串表达式s,请你实现一个基本计算器来计算并返回它的值. 整数除法仅保留整数部分. 示例: 输入:s = " ...

  2. 【前端来刷LeetCode】两数之和与两数相加

    大部分玩前端的小伙伴,在算法上都相对要薄弱些,毕竟调样式.调兼容就够掉头发的了,哪还有多余的头发再去折腾. 确实在前端中需要使用到算法的地方是比较少,但若要往高级方向发展,算法的基本功就非常重要啦.对 ...

  3. 【C语言刷LeetCode】2126. 摧毁小行星(M)

    [ 给你一个整数 mass ,它表示一颗行星的初始质量.再给你一个整数数组 asteroids ,其中 asteroids[i] 是第 i 颗小行星的质量. 你可以按 任意顺序 重新安排小行星的顺序, ...

  4. 【C语言刷LeetCode】883. 三维形体投影面积(E)

    [ 格 grid 中,我们放置了一些与 x,y,z 三轴对齐的 1 x 1 x 1 立方体. 每个值 v = grid[i][j] 表示 v 个正方体叠放在单元格 (i, j) 上. 现在,我们查看这 ...

  5. 【C语言刷LeetCode】717. 1 比特与 2 比特字符(E)

    [ 有两种特殊字符: 第一种字符可以用一比特 0 表示 第二种字符可以用两比特(10 或 11)表示 给你一个以 0 结尾的二进制数组 bits ,如果最后一个字符必须是一个一比特字符,则返回 tru ...

  6. c语言编程 插队排身高,【C语言刷LeetCode】406. 根据身高重建队列(M)

    [ 假设有打乱顺序的一群人站成一个队列. 每个人由一个整数对(h, k)表示,其中h是这个人的身高,k是排在这个人前面且身高大于或等于h的人数. 编写一个算法来重建这个队列. 注意: 总人数少于110 ...

  7. 【C语言刷LeetCode】235. 二叉搜索树的最近公共祖先(E)

    [ 给定一个二叉搜索树, 找到该树中两个指定节点的最近公共祖先. 百度百科中最近公共祖先的定义为:"对于有根树 T 的两个结点 p.q,最近公共祖先表示为一个结点 x,满足 x 是 p.q ...

  8. 【DW组队学习—LeetCode】day03

    11. 盛最多水的容器 给你 n 个非负整数 a1,a2,-,an,每个数代表坐标中的一个点 (i, ai) .在坐标内画 n 条垂直线,垂直线 i的两个端点分别为 (i, ai) 和 (i, 0) ...

  9. 【LeetCode】深搜DFS(共85题)

    [98]Validate Binary Search Tree [99]Recover Binary Search Tree [100]Same Tree [101]Symmetric Tree [1 ...

最新文章

  1. @value 数组_SpringBoot @Value 读取配置,太强大了!
  2. Hadoop系列一:Hadoop集群分布式部署
  3. kafka与zookeeper版本对应关系表
  4. Sharepoint学习笔记—Site Definition系列-- 2、创建Content Type
  5. Hbase2修复 - HBCK2
  6. python学习随笔day3
  7. Java中的网络支持Socket应用
  8. 吴恩达机器学习课程资源(笔记、中英文字幕视频、课后作业,提供百度云镜像!)
  9. 深入浅出设计模式,跟着思路快速理解
  10. 《集异璧》作者侯世达:王维、杨绛与机器翻译的本质
  11. 基于UKey数字证书实现身份认证
  12. 微服务生态组件之Spring Cloud LoadBalancer详解和源码分析
  13. 快来新宇宙:物联网与元宇宙融合发展
  14. 电子元器件行业B2B交易系统:规范企业交易流程,提升销售管理效率
  15. Android4.4 状态栏WiFi图标显示流程
  16. 有些市场上卖的卤牛肉40元一斤,是真牛肉吗?
  17. 【代码复现】ubuntu18.04复现DID-MDN问题总结
  18. 如何证明一个数能否被7整除的判定方法
  19. Java多态的理解和应用
  20. PHP手机商城毕业设计源码191803

热门文章

  1. 一年节省费用100万,AI导航误差不到1米,杭州奥体“大小莲花”智慧场馆大揭秘...
  2. 儒略日(CSP S2 第一题)
  3. PSRAM 伪静态随机存取内存
  4. 四次重启共享充电宝业务 美团终结“三电一兽”格局预言会成真吗?
  5. 为什么要做小程序?90%的商家不知道的好处!
  6. Python实现Flesch阅读易读性公式计算
  7. 【算法千题案例】每日LeetCode打卡——68.反转字符串中的元音字母
  8. 产品需求与项目需求的差异
  9. 【Java 数据结构】Map和Set
  10. 【精】JAVA各大厂问题汇总-HELLO XF