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

332.重新安排行程

首先如果只根据前后站的关系找到一种可能的行程,然后将可能的行程与当前的字符最小行程进行比较,最后得到最小行程的思路会超时,所以一定要在回溯中就确保只有字符最小的情况进入回溯。

map会对索引值进行排序,可以保证每一次都是字符最小的情况

unordered_map<string//起始站, map<string//终止站, int//起始站到终止站的票数>> targets;

是票数的统计情况,

每当我们插入一个站时,消耗了一张票,我们就把对应该票的票数减一。

由于我们已经用map确保了字符最小,所以只要我们找到一种可能的情况,就能确定他是我们所需要的情况,直接返回就行,所以这里返回值为bool,从而确保只要找到情况即刻返回,不会继续递归。

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++;
        }
    }

这里为了确保result中的站是前后有关系的,targets[result[result.size() - 1]是以result中的最后一个元素(当前的起始站)构成的map容器,这样for循环遍历的时候就能确定插入result的站点一定的前后有关的。

最后就是一定要记得加上&符号,确保每一次循环中变量中值的变化都能够记录下来。

51. N皇后

此处for循环是棋盘横向循环,每一次递归是棋盘纵向递归。

 for (int col = 0; col < n; col++) {
        if (isValid(row, col, chessboard, n)) { // 验证合法就可以放
            chessboard[row][col] = 'Q'; // 放置皇后
            backtracking(n, row + 1, chessboard);
            chessboard[row][col] = '.'; // 回溯,撤销皇后
        }
    }
}

由于这里每一次递归只插入一个皇后,一次递归棋盘中的一行,所以已经可以确定皇后满足每行不重复的条件了。

终止条件是当行数=n时,也就是递归到最后一行之后,返回chessboard。

在进行45度和135度的去重的时候,一定要注意for循环如果要同时满足两个截止条件需要加上&&号

for(int i = row - 1, j = col + 1; i >= 0 && j < n; i--, j++) {

37. 解数独

这题利用了二维递归

上题中递归遍历行,for循环遍历列,而这题是用双层for循环同时遍历行和列。

终止条件时for循环遍历完成后,证明所有格子都已经填满,循环结束

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值