代码随想录Day30 | 332.重新安排行程 51. N皇后 37. 解数独

【代码随想录训练营】【Day30】第七章|回溯算法|332.重新安排行程|51. N皇后|37. 解数独|总结 阅读详情

代码随想录Day30 | 332.重新安排行程 51. N皇后 37. 解数独

332.重新安排行程

文档讲解:代码随想录
视频讲解: 带你学透回溯算法(理论篇)
状态

本题题目有几个要求

  1. 从JFK开始
  2. 所有机票必须用一次 且 只能用一次 去重
  3. 字典序最小的路径

自己做的时候直接超时了,想法比较简单,定义了一个记录结果字符串的数组,然后用一个字符串来存储所有行程,同时为了避免一张机票被树枝上重复利用,还定义了一个used数组,其余的操作和基础回溯差不多,只不过还有一个参数是当前起飞地点的名字,用于在数组中搜寻满足这个起飞地点的航班。
整个递归函数如下

    void getTickets(vector<vector<string>>& tickets, string Name, vector<int> used)
    {
        if(count == tickets.size())
        {
            path.erase(path.size()-1);
            if(res.size() == 0)
            {
                res.push_back(path);
            }
            if(res.size() >0 && path < res[0])
            {//只存储最小的
                res.clear();
                res.push_back(path);
            }
            //cout<<res.size()<<" ";
            return;
        }
        for(int i = 0;i<tickets.size();i++)
        {
            //当不是当前Name就跳过
            if(tickets[i][0] != Name)
            {
                continue;
            }
            //已经用过就跳过
            if(used[i]==1)
            {
                continue;
            }
            used[i] = 1;
            int pathlen = path.size();
            path += tickets[i][1];
            path += ',';
            count++;
            getTickets(tickets, tickets[i][1],used);
            count--;
            path.erase(pathlen,pathlen+4);
            used[i]=0;
        }
        return ;
    }

在main函数中只需要再把res里面的字符串以“,”分割开就可以了,对于用例来说没问题,但是第11个测试时就超时了。
代码随想录中,利用map来处理排序的问题,通过建立一个哈希表unordered_map来存储机场可以与哪些机场对接,而存储对接机场因为也是一个机场集合所以使用了map<string,int>来排序并且表示了机场和该机票的使用次数。

//向下递归层数是票数
//找到从 JFK开始的机票
//所有行程 都要涉及 只能 用一次
//最小
class Solution {
unordered_map<string, map<string, int>> targets;
bool backtracking(int ticketNum, vector<string>& result) {
    if (result.size() == ticketNum + 1) {
        return true;
    }
    for (pair<const string, int>& target : targets[result[result.size() - 1]]) {
        if (target.second > 0 ) { // 记录到达机场是否飞过了
            result.push_back(target.first);
            target.second--;
            if (backtracking(ticketNum, result)) return true;
            result.pop_back();
            target.second++;
        }
    }
    return false;
}
public:
    vector<string> findItinerary(vector<vector<string>>& tickets) {
        targets.clear();
        vector<string> result;
        for (const vector<string>& vec : tickets) {
            targets[vec[0]][vec[1]]++; // 记录映射关系
        }
        result.push_back("JFK"); // 起始机场
        backtracking(tickets.size(), result);
        return result;
    }
};

N皇后

文档讲解:代码随想录
视频讲解: 这就是传说中的N皇后? 回溯算法安排!| LeetCode:51.N皇后
状态

对每一层的位置进行考虑,然后递归的深度即结果返回的时机就是处理到最后一行时,或者没有结果时。

void getSN(int n,int currow)
    {
    //当前的行数
        if(currow == n)
        {
            res.push_back(level);
            return;
        }
        //对这一行的每列进行遍历,一个遍历只能对应1个Q
        //过滤掉了行同时存在的情况
        for(int i = 0;i<n;i++)
        {
            if(isValid(currow,i,level,n))
            {
                level[currow][i] = 'Q';
                getSN(n,currow+1);
                level[currow][i] = '.';
            }
        }
        return ;
    }

在这里插入图片描述
判断是否合理可以参考上图

    //不满足的情况
    bool isValid(int currow, int curcol, vector<string> curlevel, int n)
    {
        //对于一个列
        for(int i = 0;i < currow;i++)
        {
            if(curlevel[i][curcol] == 'Q')
            {
                return false;
            }
        }
        //对于45度,从要插入位置向上搜索
        for(int i = currow-1 ,j = curcol+1;i>=0&&j<=n;i--,j++)
        {
            if(curlevel[i][j] == 'Q')
            {
                return false;
            }
        }
        //135
        for(int i = currow-1, j = curcol-1;i>=0&&j>=0;i--,j--)
        {
            if(curlevel[i][j] == 'Q')
            {
                return false;
            }
        }
        return true;
    }

37.解数独

文档讲解:代码随想录
视频讲解: 回溯算法二维递归?解数独不过如此!| LeetCode:37. 解数独
状态

二维回溯递归,对于每个点的判断1-9是否合理,如果合理就放入,然后递归,插入。如果递归过程中一直都是成立的,最后直接返回true。如果没有返回true那么就需要回溯,然后测试下一个数字放入是否合理。如果所有数字测试完都不合理,那么就需要返回false,说明这个数独无解。最终如果遍历完行和列都没有返回,那么说明处理成功直接返回true;

bool backtracking(vector<vector<char>>& board) {
    for (int i = 0; i < board.size(); i++) {        // 遍历行
        for (int j = 0; j < board[0].size(); j++) { // 遍历列
            if (board[i][j] != '.') continue;
            for (char k = '1'; k <= '9'; k++) {     // (i, j) 这个位置放k是否合适
                if (isValid(i, j, k, board)) {
                    board[i][j] = k;                // 放置k
                    if (backtracking(board)) return true; // 如果找到合适一组立刻返回
                    board[i][j] = '.';              // 回溯,撤销k
                }
            }
            return false;                           // 9个数都试完了,都不行,那么就返回false
        }
    }
    return true; // 遍历完没有返回false,说明找到了合适棋盘位置了
}

如何判断是否合理呢
在这里插入图片描述

 bool isValid(vector<vector<char>>& board, int currow, int curcol,char k)
    {
        //判断行
        for(int i = 0;i<9;i++)
        {
            if(board[currow][i] == k)
            {
                return false;
            }
        }
        //判断列
        for(int i = 0;i<9;i++)
        {
            if(board[i][curcol] == k)
            {
                return false;
            }
        }
        //判断一个九宫格
        //确定currow curcol所在的九宫格起点
        int startRow = (currow/3)*3;
        int startCol = (curcol/3)*3;
        for(int i = startRow ;i<3+startRow;i++)
        {
            for(int j = startCol;j<3+startCol;j++)
            {
                if(board[i][j] == k)
                {
                    return false;
                }
            }
        }

        return true;
    }

在这里插入图片描述

Android开发者必看:5分钟搞定DeepSeek API接入(附完整代码示例) 本文为Android开发者提供快速接入DeepSeek API的完整指南,包含环境配置、网络层设计、请求体构建等关键步骤,并附有详细代码示例。通过工程化实践,帮助开发者高效集成AI对话、代码生成等高级功能,提升移动应用竞争力。 阅读详情

相关推荐

关于Selenium3在MicrosoftEdge浏览器中出现的问题

前言 最近在做web自动化测试,所用环境是java+selenium3.141.59+MicrosoftEdge(Chromium)浏览器。 在调试的过程中,出现了很多问题。比如selenium3在Edge浏览器中远程调用中,不支持addArguments方法等 问题 1.Edge浏览器弹窗问题 在测试过程中,会出现弹出窗提示 ...

zhucheng1994的博客 2193

代码随想录Day30 332.重新安排行程、51.N皇后、37.解数独、总结

332.重新安排行程、51.N皇后、37.解数独、总结

weixin_46620779的博客 1528

用Python玩转共现分析:从NLTK到热力图可视化(附完整代码)

本文详细介绍了如何使用Python进行文本共现分析,从NLTK基础文本处理到构建共现矩阵,并实现热力图可视化。通过完整的代码示例,帮助数据分析师和开发者掌握这一揭示词语间关联网络的实用NLP技术,快速从文本中提取语义关系和主题结构。

weixin_29313817的博客 349

代码随想录算法训练营Day30|332.重新安排行程、51. N皇后、37. 解数独

在每一个行程中,如何合理处理每一个航班,使它不形成一个圈而成为死循环;如何让字母序靠前排在前面;使用回溯法的话终止条件如何确定;在搜索过程中如何遍历一个机场所对应的所有机场。N皇后是要求在二维矩阵中放置皇后,要求皇后不能同行、同列、同斜线。二维矩阵中矩阵的高就是这棵树的高度,矩阵的宽就是树形结构中每一个节点的宽度。我们用皇后们的约束条件,来回溯搜索这棵树,只要搜索到了树的叶子节点,说明就找到了皇后们的合理位置了。本题与N皇后虽然都是;类似的棋盘问题,但是更为复杂。

m0_68682181的博客 1313

ENVI+SARscape实战:从哨兵一号数据到地震形变制图全流程解析

本文详细解析了使用ENVI和SARscape软件从哨兵一号数据生成地震形变图的全流程,包括数据获取、干涉处理、相位解缠等关键步骤。通过实战技巧和参数设置建议,帮助用户高效处理SAR数据,提升地震形变监测的精度和可视化效果。

weixin_30460489的博客 385

【Bug已解决】Codex App returns 401 Missing bearer/basic authentication after login on multiple Windows la

原始报错:Codex App returns 401 Missing bearer/basic authentication after login on multiple Windows laptops场景:用户在 Windows 笔记本上登录应用成功了,但随后每个业务请求都返回 401,提示"Missing bearer/basic authentication"。登录态像是"假的"——明明登了,请求却没带任何认证信息。多台 Windows 设备都能复现。

一键难忘的博客 593

代码随想录【Day 30】| 332.重新安排行程 、51. N皇后 、37. 解数独

代码随想录【Day 30】| 332.重新安排行程 、51. N皇后 、37. 解数独

Pittsman的博客 278

Sigrity Power SI 3D-EM Full Wave Extraction模式如何进行S参数提取和观测3D电磁场和远场实例分析(一)-差分过孔结构

Sigrity Power SI 3D-EM Full Wave Extraction模式如何进行S参数提取和观测3D电磁场和远场操作指导(一)详细介绍了3D-EM Full Wave Extraction全波S参数提取,下面以一个差分过孔结构进行实例分析,以下图为例。模式如何进行S参数提取和观测3D电磁场和远场实例分析(一)-差分过孔结构。是一个简单的4层板,top换层到bottom层的差分过孔结构。起始频率为100Mhz,截止频率为20Ghz,线性扫描。上面那根曲线是插损,下面那根线是回损。

weixin_54787054的博客 343

代码随想录算法训练营第day30|332.重新安排行程 、 51. N皇后 、37. 解数独

一个机场映射多个机场,机场之间要靠字母序排列,一个机场映射多个机场,可以使用std::unordered_map,如果让多个机场之间再有顺序的话,就是用std::map 或者std::multimap 或者 std::multiset。递归深度就是row控制棋盘的行,每一层里for循环的col控制棋盘的列,一行一列,确定了放置皇后的位置。从图中,可以看出,二维矩阵中矩阵的高就是这棵树的高度,矩阵的宽就是树形结构中每一个节点的宽度。遍历multiset的时候,不能删除元素,一旦删除元素,迭代器就失效了。

qq_60513199的博客 792

损失函数大汇总(五十三)(Boundary Loss附公式推导与代码)

摘要 Boundary Loss是一种针对图像分割任务的新型损失函数,特别适用于高度类别不平衡的细粒度分割场景。与传统的区域型损失(如Dice、交叉熵)不同,它通过计算预测边界与真实边界之间的距离来优化模型,更关注边界精度而非区域重叠。核心思想是利用距离图(distance map)将边界约束转化为区域积分形式,实现端到端训练。具体实现中,损失函数为预测概率与距离图的点积,梯度仅取决于距离图,具有明确的空间引导性。相比区域型损失,Boundary Loss能更好处理小目标、细长结构等边界敏感任务,可与Dic

悦学共鸣,温柔以待,汇聚光芒,共同成长 239

手把手教你学Simulink--基于Simulink的微电网用DC-DC变换器仿真建模

微电网概述微电网:包括可再生能源发电设备、储能系统和负载,可以独立于大电网运行,也可以并网运行。重要性提高能源可靠性:通过本地化供电减少对外部电网的依赖。促进可再生能源利用:支持高效整合多种可再生能源。挑战多源管理:不同类型的能源产生方式各异,需设计灵活的电源管理系统。能量转换效率:需要高效的能量转换装置来确保能源的有效利用。通过上述步骤,我们简要介绍了如何基于Simulink进行微电网中DC-DC变换器的仿真建模。

MHD0815的博客 161

代码随想录算法训练营DAY30|332.重新安排行程、51. N皇后、37. 解数独、总结

set()和used数组去重的区别使用set去重的版本相对于used数组的版本效率都要低很多,主要是因为程序运行的时候对unordered_set 频繁的insert,unordered_set需要做哈希映射(也就是把key通过hash function映射为唯一的哈希值)相对费时间,而且insert的时候其底层的符号表也要做相应的扩充,也是费时的。而使用used数组在时间复杂度上几乎没有额外负担!使用set去重,不仅时间复杂度高了,空间复杂度也高了,在本周小结!

Greeneril_的博客 1675

第10章: MMU notifier与HMM的协作

本文摘要: HMM(Heterogeneous Memory Management)是Linux内核提供的异构内存管理框架,用于统一CPU与设备(如GPU、DSP等)的内存访问。它通过镜像页表技术实现虚拟地址空间共享,自动同步CPU和设备页表变化,支持透明的内存迁移和设备内存管理。HMM构建在mmu_interval_notifier机制上,利用序列号检测页表修改冲突,提供高效并发控制。核心数据结构包括hmm_range和HMM PFN标志位,通过hmm_range_fault()实现页表遍历和缺页处理。

图形/计算GPU的驱动与虚拟化技术分享园地 3092

代码随想录训练营Day30| 332.重新安排行程 51. N皇后 37. 解数独 总结

problems/回溯总结.md · programmercarl/leetcode-master(代码随想录出品) - Gitee.com。332. 重新安排行程 - 力扣(LeetCode)51. N 皇后 - 力扣(LeetCode)37. 解数独 - 力扣(LeetCode)332.重新安排行程。332.重新安排行程。

weixin_44174445的博客 180

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

代码随想录刷题Day30 | 332.重新安排行程 | 51. N皇后 | 37. 解数独

代码随想录刷题Day30 | 332.重新安排行程 | 51. N皇后 | 37. 解数独

DUM1615的博客 333

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

代码随想录算法训练营day30 | 332. 重新安排行程,51. N 皇后,37. 解数独

本节都是难度较高的回溯题,只要准确分辨控制树的深度和宽度的因素即可正确解题。

2301_77450803的博客 572

温度PID控制PLC程序

温度PID稳定控制程序,适用于欧姆龙PLC,对其他PLC也具有很大参考价值

代码随想录算法训练营day30|LeetCode 332. 重新安排行程、LeetCode 51 N 皇后、LeetCode 37 解数独

代码随想录算法训练营day30

qq_51588716的博客 294

代码随想录算法训练营Day30——332重新安排行程、51N皇后、37解数独

【代码】代码随想录算法训练营Day30——332重新安排行程、51N皇后、37解数独。

weixin_45075561的博客 230

零基础代码随想录【Day30】|| 332.重新安排行程,51. N皇后,37. 解数独,回溯算法总结

给定一个机票的字符串二维数组 [from, to],子数组中的两个成员分别表示飞机出发和降落的机场地点,对该行程进行重新规划排序。一个数独的解法需遵循如下规则: 数字 1-9 在每一行只能出现一次。数字 1-9 在每一列只能出现一次。每一种解法包含一个不同的 n 皇后问题 的棋子放置方案,该方案中 'Q' 和 '.' 分别代表了皇后和空位。n 皇后问题 研究的是如何将 n 个皇后放置在 n×n 的棋盘上,并且使皇后彼此之间不能相互攻击。给你一个整数 n ,返回所有不同的 n 皇后问题 的解决方案。

Andrew______的博客 480

代码随想录算法训练营 | day30 回溯总结,332.重新安排行程,51.N皇后,37.解数独

本题其实可以算是一道hard的题目了,关于本题的难点我在文中已经列出了。如果单纯的回溯搜索(深搜)并不难,难还难在容器的选择和使用上。本题其实是一道深度优先搜索的题目,但是我完全使用回溯法的思路来讲解这道题题目,算是给大家拓展一下思维方式,其实深搜和回溯也是分不开的,毕竟最终都是用递归。代码随想录 (programmercarl.com)回溯专题汇聚为一张图:这个图是莫非毛,所画,总结的非常好,分享给大家。

weixin_45011378的博客 260

代码随想录算法训练营Day30 | 332.重新安排行程 51. N皇后 37. 解数独 总结

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

qq_24817679的博客 367

代码随想录 -- day30 -- 332.重新安排行程 、51. N皇后、37. 解数独

一个机场映射多个机场,机场之间要靠字母序排列,一个机场映射多个机场,可以使用std::unordered_map,如果让多个机场之间再有顺序的话,就是用std::map 或者std::multimap 或者 std::multiset。拿题目中的示例为例,输入: [["MUC", "LHR"], ["JFK", "MUC"], ["SFO", "SJC"], ["LHR", "SFO"]] ,这是有4个航班,那么只要找出一种行程,行程里的机场个数是5就可以了。1、确定递归函数和参数。2、135度没有棋子。

Accelerated的博客 1005

代码随想录 Day30 332.重新安排行程 51. N皇后 37. 解数独

如果说该层是可以的但是向下递归的时候下一层没有一个是可以的话,这个时候就会return false;2. 开始的时候就设置两个for循环,并没有像以前一样设置终止条件,也是因为只要是有一种符合的情况的话就可以,所以说设置为bool。2. 注意比较的时候是对于一个char类型的元素进行比较而不是一个int进行比较,需要注意输入以及输出的类型,还有就是加’‘。1. (i/3)*3和(i/3)*3+3是一个小的九宫格的范围,小的点不要忘记*3。思路:本题的思路是很有难度的,跟着卡哥的思想写确实就简单了很多。

weixin_61057535的博客 454

代码随想录Day30-332.重新安排行程,51. N皇后,37. 解数独

【代码】代码随想录Day30-332.重新安排行程,51. N皇后,37. 解数独。

lizhiqiang502的博客 94

代码随想录算法训练营day30 | 332.重新安排行程 51. N皇后 37. 解数独

回溯结束

baimaozi_007的博客 259

代码随想录算法训练营 Day 30 | 332.重新安排行程,51.N皇后,37.解数独

代码随想录-回溯算法总结。

MisakaMirai的博客 100
上一篇: 代码随想录Day29 | 491.递增子序列 46.全排列 47.全排列 II
下一篇: 代码随想录Day31 | 贪心算法 455.分发饼干 376. 摆动序列 53. 最大子序和
sRiddle
博客等级 码龄7年 528粉丝 63原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值