【AcWing19】【LeetCode】DFS - 46/47/39/77/216/17

news2024/11/23 23:32:56

文章目录

  • 代码随想录在B站的视频讲得比AcWing好
  • 模板题1:排列数字
  • 模板题2:n皇后
    • 方法一
    • 方法二
  • LeetCode 46. 全排列
  • LeetCode 47. 全排列 II (重复元素)
  • LeetCode 39. 组合总和
  • LeetCode 77. 组合
  • LeetCode 216. 组合总和 III
  • LeetCode 17. 电话号码的字母组合

代码随想录在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变成1
            st[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);
	// 初始化g
	for(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 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调整startIndex
            sum -= 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指向的数字转为int
        string 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)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

在这里插入图片描述

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

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

相关文章

黑马点评--分布式锁

黑马点评–分布式锁 基本原理与不同实现方式对比&#xff1a; 什么是分布式锁&#xff1a; ​ 分布式锁&#xff1a;满足分布式系统或集群模式下多进程可见并且互斥的锁。 分布式锁的核心是实现多进程之间互斥&#xff0c;而满足这一点的方式有很多&#xff0c;常见的有三种…

Leetcode799. 香槟塔

文章目录题目链接题目大意解题思路代码(C)递推递归题目链接 点我 (^_^) 题目大意 解题思路 一开始看到这个 poured 范围这么大&#xff0c;以为是可以直接推出数学公式&#xff0c;但推了半天没推出来。 然后发现&#xff0c;直接从顶部开始模拟即可&#xff0c;某个row 下的…

HIve数仓新零售项目DWB层的构建

HIve数仓新零售项目 注&#xff1a;大家觉得博客好的话&#xff0c;别忘了点赞收藏呀&#xff0c;本人每周都会更新关于人工智能和大数据相关的内容&#xff0c;内容多为原创&#xff0c;Python Java Scala SQL 代码&#xff0c;CV NLP 推荐系统等&#xff0c;Spark Flink Kaf…

October 2019 Twice SQL Injection

目录 首先&#xff0c;尝试一下回显位的个数 第二步获取数据库名称 第三步&#xff0c;获得表名 第四步&#xff0c;获得列名 最后获取flag 总结 &#xff1a;二次注入&#xff0c;首先我们需要锁定是哪里哪个文本框存在二次注入&#xff0c;以这道题为例&#xff0c;首先…

计算机视觉算法——基于Transformer的语义分割(SETR / Segmenter / SegFormer)

计算机视觉算法——基于Transformer的语义分割&#xff08;SETR / Segmenter / SegFormer&#xff09;1. SETR1.1 网络结构及特点1.1.1 Decoder1.2 实验2. Segmenter2.1 网络结构及特点2.1.1 Decoder2.2 实验3. SegFormer3.1 网络结构及特点3.1.1 Overlap Patch Merging3.1.2 E…

CMSC5713-IT项目管理之八、敏捷项目管理Agile Project Management

文章目录8.1. Traditional SDLC8.2. Agile Methodologies8.3. Scrum8.3.1. Roles8.3.2. User Story8.3.3. Product Backlog8.3.4. Release Backlog8.3.5. Sprint Backlog8.3.6. Estimation8.3.7. Burning-down Chart8.3.8. Planning Meetings8.3.8.1. Daily Scrum Meeting8.3.8…

stm32f334timer15-17

stm32f334timer15-17介绍TIM15主要功能TIM16-17主要功能TIM15/TIM16/TIM17功能描述时基单位预分频器描述计数器模式递增计数模式重复计数器时钟选择捕获/比较频道输入捕获模式PWM输入模式&#xff08;仅适用于TIM15&#xff09;强制输出模式输出比较模式组合PWM模式&#xff08…

基于Springboot+vue开发实现自行车租赁管理系统

作者主页&#xff1a;编程千纸鹤 作者简介&#xff1a;Java、前端、Pythone开发多年&#xff0c;做过高程&#xff0c;项目经理&#xff0c;架构师 主要内容&#xff1a;Java项目开发、毕业设计开发、面试技术整理、最新技术分享 收藏点赞不迷路 关注作者有好处 项目编号&…

基于java学生选课系统

开发工具eclipse,jdk1.8 技术&#xff1a;java swing 数据库&#xff1a;mysql5.7 学生选课系统功能&#xff1a;管理员、教师、学生三个角色 一、管理员功能&#xff1a; 1.登录、修改密码、退出系统 2.学生管理&#xff1a;添加、修改、删除、查询 3.班级管理&#xff1a;添加…

力扣(LeetCode)23. 合并K个升序链表(C++)

模拟k路归并 朴素思想&#xff0c;类比二路归并&#xff0c; kkk 路归并多了一些参与比较的链表。我们可以在循环体内多一层循环&#xff0c;找到值最小的结点&#xff0c;插入答案链表的尾部。 朴素算法的时间复杂度 O(k∑i0k−1listsi.size())O(k\times\sum_{i0}^{k-1} lis…

做公众号1年啦

大家好&#xff0c;我是洋子 这里是北京的宇宙中心&#xff0c;西二旗地铁站&#xff0c;川流不息的人群&#xff0c;不断前进的脚步声&#xff0c;好像在告诉我们&#xff0c;新的一天工作即将开始 在地铁上&#xff0c;有人拿着手机刷着短视频&#xff0c;似乎还不想面对今…

第三十四篇 生命周期 - 易理解

通过之前一系列内容的推进来到生命周期的内容了&#xff0c;那么对于生命周期图示这块内容原文档内容有这么一段话&#xff1a;You don’t need to fully understand everything going on right now, but as you learn and build more, it will be a useful reference.&#xf…

jenkins构建gitee项目

流程是代码提交到gitee&#xff0c;jenkins中点击构建&#xff0c;自动删除目标服务器之前运行的jar包、拉取代码、构建、将jar包传到目标服务器、运行jar包。 1.下载jenkins运行 java -jar jenkins.war --httpPort8084 然后根据初始密码&#xff0c;创建账号&#xff0c;下载…

同花顺_代码解析_技术指标_P、Q

本文通过对同花顺中现成代码进行解析&#xff0c;用以了解同花顺相关策略设计的思想 目录 PBX PRICEOSC PSY PSYFS PVT QACD QLCX QLDX PBX 瀑布线 PBX1:(收盘价的M1日移动平均收盘价的M1*2日简单移动平均收盘价的M1*4日简单移动平均)/3 PBX2:(收盘价的M2日移动平均收…

320力扣周赛总结

目录 一、三元组数目 二、二叉树最近结点查询 三、到达首都的最少油耗 四、完美分割的方案数 一、三元组数目 6241. 数组中不等三元组的数目https://leetcode.cn/problems/number-of-unequal-triplets-in-array/ 思路&#xff1a;数据范围都非常小&#xff0c;三重循环即可…

Linux下的的GDB调试技巧一 —— 基础知识和介绍

基础知识 BUG BUG是一个英文单词&#xff0c;本意是指昆虫、小虫、损坏、犯贫、缺陷、窃听器等意思。在本文中是计算机领域专业术语&#xff0c;一般是指在电脑系统或程序中&#xff0c;隐藏着的一些未被发现的缺陷或问题&#xff0c;简称程序漏洞。另外bug还有一种引申意义&a…

MySQL表的增删改查操作(CRUD)

1. 新增1.1 插入一行全列插入1.2 插入多行指定列插入2. 查询2.1 全列查询2.2 指定列查询2.3 查询字段为表达式2.4 起个别名 as2.5 去重 distinct2.6 排序 order by2.7 条件查询 where2.8 分页查询 limit3. 修改 update4. 删除 delete增删查改(CRUD)即:增加(Create)、查询(Retri…

STC51单片机34——五线四相步进电机驱动(1个步进电机)

/*-------------------------------------------------------------------------------- MCU: STC15W408AS 注意其没有T1&#xff0c;但是有T2 开发板: STC15W408AS最小系统板 晶振: 内部时钟11.0592M&#xff0c;波特率3…

JavaScript面向对象:面向过程与面向对象

面向对象编程介绍 两大编程思想 面向过程 面向对象 面向过程编程 POP(Process-oriented programming) 面向过程就是分析出解决问题所需要的步骤&#xff0c;然后用函数把这些步骤一步一步实现&#xff0c;使用的时候再一个一个的依次调用就可以了。 举个栗子&#xff1a;…

STM32 CRC计算单元(循环冗余校验)

STM32第三篇【1】STM32 CRC计算单元【2】STM32 CRC简介【3】STM32 CRC主要特性【4】STM32 CRC功能描述【5】STM32 CRC寄存器【6】STM32 数据寄存器&#xff08;CRC_DR&#xff09;【7】STM32 独立数据寄存器&#xff08;CRC_IDR&#xff09;【8】STM32 控制寄存器&#xff08;C…