【算法】回溯算法专题③ ——排列型回溯 python

news/2025/2/5 7:12:47/

目录

  • 前置
  • 小试牛刀
  • 回归经典
  • 举一反三
  • 总结


前置


算法】回溯算法专题① ——子集型回溯 python
算法】回溯算法专题② ——组合型回溯 + 剪枝 python


小试牛刀


全排列 https://leetcode.cn/problems/permutations/description/


给定一个不含重复数字的数组 nums ,返回其 所有可能的全排列 。你可以 按任意顺序 返回答案。

示例 1:

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

示例 2:

输入:nums = [0,1]
输出:[[0,1],[1,0]]
示例 3:

输入:nums = [1]
输出:[[1]]

提示:

1 <= nums.length <= 6
-10 <= nums[i] <= 10
nums 中的所有整数 互不相同

思路:

用一个vis标记数组:对已选的数字打上标记


题解:

python">class Solution:def permute(self, nums: List[int]) -> List[List[int]]:n = len(nums)path = []ans = []vis = [0] * (n + 1)def dfs(i):if i == n:ans.append(path.copy())returnfor j in range(n):if not vis[j]:vis[j] = 1path.append(nums[j])dfs(i + 1)path.pop()vis[j] = 0 # 别忘了回溯时将vis打回0dfs(0)return ans

当然vis标记数组可以通过递归时传入一个set参数代替


题解2:

python">class Solution:def permute(self, nums: List[int]) -> List[List[int]]:n = len(nums)path = []ans = []def dfs(i, s): # s:setif i == n:ans.append(path.copy())returnfor x in s:path.append(x)dfs(i + 1, s - {x})path.pop()dfs(0, set(nums)) # 用集合可以 O(1)判断元素是否在里面return ans


回归经典


N皇后 https://leetcode.cn/problems/n-queens/description/

按照国际象棋的规则,皇后可以攻击与之处在同一行或同一列或同一斜线上的棋子。

n 皇后问题 研究的是如何将 n 个皇后放置在 n×n 的棋盘上,并且使皇后彼此之间不能相互攻击。

给你一个整数 n ,返回所有不同的 n 皇后问题 的解决方案。

每一种解法包含一个不同的 n 皇后问题 的棋子放置方案,该方案中 ‘Q’ 和 ‘.’ 分别代表了皇后和空位。


示例 1:

在这里插入图片描述
输入:n = 4
输出:[[“.Q…”,“…Q”,“Q…”,“…Q.”],[“…Q.”,“Q…”,“…Q”,“.Q…”]]
解释:如上图所示,4 皇后问题存在两个不同的解法。

示例 2:

输入:n = 1
输出:[[“Q”]]

提示:
1 <= n <= 9


思路:

同一对角线不能有多个皇后
(可以通过计算行号加或减列号来判断)


在这里插入图片描述

题解code:

python">class Solution:def solveNQueens(self, n: int) -> List[List[str]]:ans = []col = [0] * n  # col:列vis = [0] * n  # vis:标记数组diag1 = [0] * (2 * n)diag2 = [0] * (2 * n)# 分别表示两个对角线def dfs(r):  # row:行if r == n:ans.append(["." * c + "Q" + "." * (n - 1 - c) for c in col])returnfor c in range(n):if not vis[c] and not diag1[r + c] and not diag2[r - c]:col[r] = cvis[c] = diag1[r + c] = diag2[r - c] = 1dfs(r + 1)vis[c] = diag1[r + c] = diag2[r - c] = 0dfs(0)return ans




举一反三


小小变化一下,可以在对角线上,但有前提: 行号至少相差3

受伤的皇后 https://www.lanqiao.cn/problems/552/learning/

在这里插入图片描述

思路:

主要问题在于判断相同对角线上行号之差
以(2, 2)为例:
【右对角线】 的点是 (1, 3),【左对角线】 的点是 (3, 3),
可以发现:
(2, 2)和 (1, 3)的横坐标之差的绝对值=纵坐标之差的绝对值
同样的(2, 2)和 (3, 3)亦是如此,
所以判断两点是否在同一对角线,
即判断这两点的横纵坐标绝对值之差是否相等


题解code:

python">col = [0] * n
vis = [0] * n
diag1 = [0] * 2 * n
diag2 = [0] * 2 * ndef check(x, y):if not vis[y] and not diag1[x + y] and not diag2[x - y]:for i in range(x):if abs(i - x) == abs(col[i] - y) and abs(x - i) < 3:return 0return 1return 0def dfs(r):if r == n:global ansans += 1returnfor c in range(n):if check(r, c):col[r] = cvis[c] = diag1[r + c] = diag2[r - c] = 1dfs(r + 1)col[r] = 0vis[c] = diag1[r + c] = diag2[r - c] = 0n = int(input())
ans = 0
dfs(0)
print(ans)


总结


回溯法是一种通过尝试每一种可能性来找到所有解的算法。对于N皇后问题,特别是带有额外约束条件的问题(如本题中的皇后之间在同一条45度角斜线上至少相隔3行),回溯法是一个非常合适的选择。


END
如果有更多问题或需要进一步的帮助,可以在评论区留言讨论哦!
如果喜欢的话,请给博主点个关注 谢谢


http://www.ppmy.cn/news/1569443.html

相关文章

day38|leetcode 322零钱兑换,279.完全平方数,139.单词拆分

322. 零钱兑换 给你一个整数数组 coins &#xff0c;表示不同面额的硬币&#xff1b;以及一个整数 amount &#xff0c;表示总金额。 计算并返回可以凑成总金额所需的 最少的硬币个数 。如果没有任何一种硬币组合能组成总金额&#xff0c;返回 -1 。 你可以认为每种硬币的数量是…

计算机网络——三种交换技术

目录 电路交换——用于电话网络 电路交换的优点&#xff1a; 电路交换的缺点&#xff1a; 报文交换——用于电报网络 报文交换的优点&#xff1a; 报文交换的缺点&#xff1a; 分组交换——用于现代计算机网络 分组交换的优点&#xff1a; 分组交换的缺点 电路交换——…

第六章:化神-React公告功能实战

公告功能实现 工具可以发布公告、通知等消息 , 可查看公告是否已读,可指定用户去发布公告 表设计CREATE TABLE `t_notice` (`notice_id` int(11

跨组织环境下 MQTT 桥接架构的评估

论文标题 中文标题&#xff1a; 跨组织环境下 MQTT 桥接架构的评估 英文标题&#xff1a; Evaluation of MQTT Bridge Architectures in a Cross-Organizational Context 作者信息 Keila Lima, Tosin Daniel Oyetoyan, Rogardt Heldal, Wilhelm Hasselbring Western Norway …

【Java】位图 布隆过滤器

位图 初识位图 位图, 实际上就是将二进制位作为哈希表的一个个哈希桶的数据结构, 由于二进制位只能表示 0 和 1, 因此通常用于表示数据是否存在. 如下图所示, 这个位图就用于标识 0 ~ 14 中有什么数字存在 可以看到, 我们这里相当于是把下标作为了 key-value 的一员. 但是这…

自动化软件测试的基本流程

一、自动化测试的准备 1.1 了解测试系统 首先对于需要测试的系统我们需要按照软件需求说明书明确软件功能。这里以智慧养老系统作为案例进行测试&#xff0c;先让我们看看该系统的登录界面和用户管理界面。 登录界面&#xff1a; 登录成功默认界面&#xff1a; 用户管理界面…

网站快速收录:如何优化网站音频内容?

本文转自&#xff1a;百万收录网 原文链接&#xff1a;https://www.baiwanshoulu.com/60.html 为了优化网站音频内容以实现快速收录&#xff0c;以下是一些关键的策略和步骤&#xff1a; 一、高质量音频内容创作 原创性&#xff1a; 确保音频内容是原创的&#xff0c;避免使…

前端力扣刷题 | 6:hot100之 矩阵

73. 矩阵置零 给定一个 m x n 的矩阵&#xff0c;如果一个元素为 0 &#xff0c;则将其所在行和列的所有元素都设为 0 。请使用 原地 算法。 法一&#xff1a; var setZeroes function(matrix) {let setX new Set(); // 用于存储需要置零的行索引let setY new Set(); //…