实验四:回溯算法的设计与分析

某不知名学校大二算法课实验报告

题目来自力扣

第一题:幂集

力扣题目链接:幂集

题目描述:

幂集。编写一种方法,返回某集合的所有子集。集合中不包含重复的元素。

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

示例:

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

 输出:

[

  [3],

  [1],

  [2],

  [1,2,3],

  [1,3],

  [2,3],

  [1,2],

  []

]

经典的递归实现指数型枚举的模板题

画出递归搜索树,一层一层递归回溯即可

注意每次要恢复现场

模板大体如下:

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

注释+代码如下:

class Solution {
public:vector<vector<int>>res; //答案vector<int>temp; //保存路径void dfs(vector<int>&nums, int value, int j) {if(value == temp.size()) //选到最后一个数时{res.push_back(temp); //保存路径}for(int i = j ; i < nums.size(); i ++ ){temp.push_back(nums[i]);dfs(nums,value, i + 1);temp.pop_back();//还原现场}}vector<vector<int>> subsets(vector<int>& nums) {int n = nums.size();for(int i = 1; i <= n; i ++ ){dfs(nums, i , 0); // 传入数组,第几个数,已选第几个数}res.push_back(vector<int>{});return res;}
};

第二题:N皇后Ⅱ

力扣题目链接:N皇后Ⅱ

题目描述:

给定一个整数 n,返回 n 皇后不同的解决方案的数量。

示例:

输入: 4

输出: 2

解释: 4 皇后问题存在如下两个不同的解法。

[

 [".Q..",  // 解法 1

  "...Q",

  "Q...",

  "..Q."],

 ["..Q.",  // 解法 2

  "Q...",

  "...Q",

  ".Q.."]

]

这道题居然是困难? 这是一道非常非常经典的板子题,学习搜索必定会遇到的一道题

这题我的思路是通过行h搜索,cot,dg,udg分别标记列,对角线和反对角线

首先全部格子默认成'.', 枚举每一个位置能不能放‘Q’,符合条件则res ++ ;

代码+注释如下:

class Solution {
public://const int N = 10;bool cot[20], dg[20], udg[20];char g[20][20];int res;void dfs(int h,int n){if( h == n) // 达到矩阵大小 答案加一{res ++ ;return;}for(int l = 0; l < n; l ++ ){//对角线h + l, 那么反对角线就是 n + h - lif(!cot[l] && !dg[h + l] && !udg[n + h - l]){g[h][l] = 'Q';cot[l] = dg[h + l] = udg[n + h - l] = true;dfs(h + 1, n);cot[l] = dg[h + l] = udg[n + h - l] = false;g[h][l] = '.';}}}int totalNQueens(int n) {for(int i = 0; i < n; i ++ ){for(int j = 0; j < n; j ++ ){g[i][j] = '.'; // 初始化}}dfs(0,n);return res;}
};

第三题:全排列

力扣题目链接:全排列

题目描述:

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

示例:

输入: [1,2,3]

输出:

[

  [1,2,3],

  [1,3,2],

  [2,1,3],

  [2,3,1],

  [3,1,2],

  [3,2,1]

]

这道题和第一题必须好好地对比学习,第一题是实现指数型枚举,这一题是实现排列型枚举

同样都是选不选的问题,同样都是递归搜索和回溯的问题,不过这会要多开一个数组保存路径

st数组标记有没有选过这个数字

代码如下:

class Solution {
public:vector<vector<int>>path;vector<int>temp;bool st[10];void dfs(int u, int n, vector<int>& nums){if(temp.size() == n){path.push_back(temp);return;}else{for(int i = 0; i < n; i ++ ){if(st[i] == false){st[i] = true;temp.push_back(nums[i]);dfs(u + 1, n, nums);temp.pop_back();st[i] = false;}}}}vector<vector<int>> permute(vector<int>& nums) {dfs(0, nums.size(), nums);return path;}};

第四题:二进制手表

力扣题目链接:二进制手表

题目描述:

二进制手表顶部有 4 个 LED 代表 小时(0-11),底部的 6 个 LED 代表 分钟(0-59)。每个 LED 代表一个 0 或 1,最低位在右侧。

  • 例如,下面的二进制手表读取 "4:51" 。

给你一个整数 turnedOn ,表示当前亮着的 LED 的数量,返回二进制手表可以表示的所有可能时间。你可以 按任意顺序 返回答案。

小时不会以零开头:

  • 例如,"01:00" 是无效的时间,正确的写法应该是 "1:00" 。

分钟必须由两位数组成,可能会以零开头:

  • 例如,"10:2" 是无效的时间,正确的写法应该是 "10:02" 。

示例 1:

输入:turnedOn = 1
输出:["0:01","0:02","0:04","0:08","0:16","0:32","1:00","2:00","4:00","8:00"]

示例 2:

输入:turnedOn = 9
输出:[]

提示:

  • 0 <= turnedOn <= 10

思路:

构建一个可选择hour和minutes的数组,这里选择其实一共就是这10个bit,便于快速查找
递归时候就是看turnedOn是否被用完了,用完则返回结果;同时为了避免重复,每次遍历选择只选择当前序号后的数字;
剪枝: 排除不允许的情况 hour<=11 和 minutes<=59

代码+注释如下:

class Solution {
public:vector<string>res;void dfs(string& s, int start, int pointNum){if(pointNum == 3){if(isValid(s, start, s.size() - 1)){res.emplace_back(s);}return;}for(int i = start; i < s.size(); i ++ ){if(isValid(s, start, i)) {   s.insert(s.begin() + i + 1, '.'); // 插入点pointNum ++;dfs(s, i + 2, pointNum);pointNum -- ;s.erase(s.begin() + i + 1); //恢复现场} else break;}}bool isValid(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] > '9' || s[i] < '0') {return false;}num = num * 10 + (s[i] - '0');if(num > 255){return false;}}return true;}vector<string> restoreIpAddresses(string s) {if(s.size() < 4 || s.size() > 12) return res;dfs(s, 0, 0);return res;}
};

第五题:复原ip地址

力扣题目链接:复原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"]

示例 4:

输入:s = "010010"

输出:["0.10.0.10","0.100.1.0"]

示例 5:

输入:s = "101023"

输出:["1.0.10.23","1.0.102.3","10.1.0.23","10.10.2.3","101.0.2.3"]

 提示:

0 <= s.length <= 3000

s 仅由数字组成

切割问题,跟一道题切割回文子串很像,主要是检查函数isValid难写

搜索过程如下:

代码+注释如下:

class Solution {
public:vector<string>res;void dfs(string& s, int start, int pointNum){if(pointNum == 3) //3个点分4段{if(isValid(s, start, s.size() - 1)){res.emplace_back(s); //函数功能类似于push_back}return;}for(int i = start; i < s.size(); i ++ ){if(isValid(s, start, i)) {   s.insert(s.begin() + i + 1, '.'); // 插入点pointNum ++;dfs(s, i + 2, pointNum);pointNum -- ;s.erase(s.begin() + i + 1); //恢复现场} else break;}}bool isValid(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] > '9' || s[i] < '0') {return false;}num = num * 10 + (s[i] - '0');if(num > 255){return false;}}return true;}vector<string> restoreIpAddresses(string s) {if(s.size() < 4 || s.size() > 12) return res;dfs(s, 0, 0);return res;}
};

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

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

相关文章

【C++ Primer Plus学习记录】指针——指针和字符串

数组和指针的特殊关系可以扩展到C-风格字符串。请看下面的代码&#xff1a; char flower[10] "rose"; cout << flower << "s are red\n"; 数组名是第一个元素的地址&#xff0c;因此cout语句中的flower是包含字符r的char元素的地址。cout对…

Leetcode刷题详解——长度最小的子数组

1. 题目链接&#xff1a;209. 长度最小的子数组 2. 题目描述&#xff1a; 给定一个含有 n 个正整数的数组和一个正整数 target 。 找出该数组中满足其总和大于等于 target 的长度最小的 连续子数组 [numsl, numsl1, ..., numsr-1, numsr] &#xff0c;并返回其长度**。**如果不…

Tang Capital宣布收购纳斯达克上市公司Rain Oncology100%股权

来源&#xff1a;猛兽财经 作者&#xff1a;猛兽财经 猛兽财经获悉&#xff0c;纳斯达克上市公司Rain Oncology(Rain)宣布近期已收到Tang Capital Partners旗下的子公司Concentra Biosciences以每股1.25美元的现金收购要约。 这家临床阶段微型市值癌症治疗药物开发商的股价在消…

Java第三方登录封装工具类

Java中可以使用第三方登录来简化用户登录流程&#xff0c;常见的第三方登录如QQ、微信、微博等。下面是一个Java封装第三方登录的工具类&#xff1a; import java.io.IOException; import java.util.HashMap; import java.util.Map;import org.apache.http.client.ClientProto…

apache shiro安全框架反序列化漏洞

shiro是开源安全框架&#xff0c;它干净利落地处理身份认证&#xff0c;授权&#xff0c;企业会话管理和加密。 参见文章&#xff1a;百度安全验证 用linux搭建一个环境 配置下源vi /etc/apt/sources.list 源如果是kali官方的有时候会下载不了&#xff0c;改成中科大的源 更…

【Proteus仿真】【51单片机】电蒸锅温度控制系统

文章目录 一、功能简介二、软件设计三、实验现象联系作者 一、功能简介 本项目使用Proteus8仿真51单片机控制器&#xff0c;使用LCD1602液晶、按键开关、蜂鸣器、DS18B20温度传感器&#xff0c;液位传感器、继电器控制加热保温装置等。 主要功能&#xff1a; 系统运行后&#…

英国人工智能公司【TitanML】完成280万美元融资

来源&#xff1a;猛兽财经 作者&#xff1a;猛兽财经 猛兽财经获悉&#xff0c;总部位于英国伦敦的人工智能公司【TitanML】近期宣布已完成280万美元种子轮融资&#xff0c;该公司的产品允许机器学习团队部署大型语言模型(llm)。 本轮融资由Octopus Ventures领投&#xff0c;还…

Python文件共享+cpolar内网穿透:轻松实现公网访问

文章目录 1.前言2.本地文件服务器搭建2.1.Python的安装和设置2.2.cpolar的安装和注册 3.本地文件服务器的发布3.1.Cpolar云端设置3.2.Cpolar本地设置 4.公网访问测试5.结语 1.前言 数据共享作为和连接作为互联网的基础应用&#xff0c;不仅在商业和办公场景有广泛的应用&#…

【LeetCode】5. 最长回文子串

1 问题 给你一个字符串 s&#xff0c;找到 s 中最长的回文子串。 如果字符串的反序与原始字符串相同&#xff0c;则该字符串称为回文字符串。 示例 1&#xff1a; 输入&#xff1a;s “babad” 输出&#xff1a;“bab” 解释&#xff1a;“aba” 同样是符合题意的答案。 示…

【Codeforces】Codeforces Round 903 (Div. 3)【待补】

Dashboard - Codeforces Round 903 (Div. 3) - Codeforces Problem - C - Codeforces Problem - D - Codeforces

进程的虚拟地址空间

一、 对于C/C程序员&#xff0c;我们看到的程序中的地址&#xff0c;都不是物理地址&#xff0c;而是操作系统映射的虚拟地址/线性地址&#xff0c;每一个进程都映射了同样结构的虚拟地址空间&#xff0c;让进程以为自己在独享内存资源&#xff0c;下图是以Linux下32位操作系统…

spark stream入门案例:netcat准实时处理wordCount(scala 编程)

目录 案例需求 代码 结果 解析 案例需求&#xff1a; 使用netcat工具向9999端口不断的发送数据&#xff0c;通过SparkStreaming读取端口数据并统计不同单词出现的次数 -- 1. Spark从socket中获取数据&#xff1a;一行一行的获取 -- 2. Driver程序执行时&#xff0c…

Lock使用及效率分析(C#)

针对无Lock、Lock、ReadWriterLock、ReadWriterLockSlim四种方式&#xff0c;测试在连续写的情况下&#xff0c;读取的效率&#xff08;原子操作Interlocked由于使用针对int,double等修改的地方特别多&#xff0c;而且使用范围受限&#xff0c;所以本文章没有测试&#xff09; …

【C++ 成员函数与非成员函数:选择正确的工具】

在C编程中&#xff0c;成员函数和非成员函数都是关键的概念。它们提供了不同的方法来组织和处理代码&#xff0c;具有各自的优势和用途。本文将深入研究成员函数和非成员函数&#xff0c;以帮助您了解何时使用它们以及如何做出正确的选择。 成员函数&#xff1a;类的内在力量 …

服务器带宽和流量的关系

服务器带宽和流量的关系 我们经常听说带宽&#xff0c;流量等这样一些专用名词&#xff0c;平常生活中手机使用会用到&#xff0c;在IT行业搭建网站使用服务器也会用到&#xff0c;虽然这两个流量带宽意义上不全相同&#xff0c;但是毕竟是我们比较关注的内容。今天给大家说说…

C/C++笔试易错与高频题型图解知识点(二)—— C++部分(持续更新中)

目录 1.构造函数初始化列表 1.1 构造函数初始化列表与函数体内初始化区别 1.2 必须在初始化列表初始化的成员 2 引用&引用与指针的区别 2.1 引用初始化以后不能被改变&#xff0c;指针可以改变所指的对象 2.2 引用和指针的区别 3 构造函数与析构函数系列题 3.1构造函数与析…

2023大联盟6比赛总结

比赛链接 反思 A 为什么打表就我看不出规律&#xff01;&#xff01;&#xff01; 定式思维太严重了T_T B 纯智障分块题&#xff0c;不知道为什么 B 100 B100 B100 比理论最优 B 300 B300 B300 更优&#xff08;快了 3 倍&#xff09;&#xff0c;看来分块还是要学习一…

【LeetCode热题100】--287.寻找重复数

287.寻找重复数 方法&#xff1a;使用快慢指针 使用环形链表II的方法解题&#xff08;142.环形链表II&#xff09;&#xff0c;使用 142 题的思想来解决此题的关键是要理解如何将输入的数组看作为链表。 首先明确前提&#xff0c;整数的数组 nums 中的数字范围是 [1,n]。考虑一…

VScode无法跳转函数定义

VScode需要在当前工作环境下解析函数之间的依赖关系&#xff0c;如果工作环境是根目录/&#xff0c;扫描的文件范围会比/home/username/code大很多&#xff0c;导致VScode无法解析出函数依赖&#xff0c;也就无法跳转。 解决办法&#xff1a;将路径目录从高目录调整到较低的目…

【Qt控件之QDialogButtonBox】概述及使用

概述 QDialogButtonBox类是一个小部件&#xff0c;它以适合当前小部件样式的布局呈现按钮。 对话框和消息框通常以符合该台界面指南的布局呈现按钮。不同的平台会有不同的对话框布局。QDialogButtonBox允许发人员向其添加按钮&#xff0c;并将自使用用户的桌面环境所适合的布局…