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

news2025/2/4 20:07:09

目录

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


前置


【算法】回溯算法专题① ——子集型回溯 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标记数组:对已选的数字打上标记


题解:

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())
                return
            for j in range(n):
                if not vis[j]:
                    vis[j] = 1
                    path.append(nums[j])
                    dfs(i + 1)
                    path.pop()
                    vis[j] = 0 # 别忘了回溯时将vis打回0

        dfs(0)
        return ans

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


题解2:

class Solution:
    def permute(self, nums: List[int]) -> List[List[int]]:
        n = len(nums)
        path = []
        ans = []

        def dfs(i, s): # s:set
            if i == n:
                ans.append(path.copy())
                return
            for 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:

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])
                return
            for c in range(n):
                if not vis[c] and not diag1[r + c] and not diag2[r - c]:
                    col[r] = c
                    vis[c] = diag1[r + c] = diag2[r - c] = 1
                    dfs(r + 1)
                    vis[c] = diag1[r + c] = diag2[r - c] = 0

        dfs(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:

col = [0] * n
vis = [0] * n
diag1 = [0] * 2 * n
diag2 = [0] * 2 * n

def 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 0
        return 1
    return 0

def dfs(r):
    if r == n:
        global ans
        ans += 1
        return
    for c in range(n):
        if check(r, c):
            col[r] = c
            vis[c] = diag1[r + c] = diag2[r - c] = 1
            dfs(r + 1)
            col[r] = 0
            vis[c] = diag1[r + c] = diag2[r - c] = 0
            
n = int(input())
ans = 0
dfs(0)
print(ans)


总结


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


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

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

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

相关文章

Vue2.x简介

Vue2.x简介 Vue2.x的版本介绍Vue2.x的两大组件库 Vue2.x的版本介绍 Vue2.x是vue.js的第二个主要版本&#xff0c;最初版发布于2016 年&#xff0c;最终版发布于2023年12月24日&#xff08;版本号&#xff1a;2.7.16&#xff0c;版本名&#xff1a;Swan Song&#xff08;绝唱&a…

FFmpeg:多媒体处理的瑞士军刀

FFmpeg&#xff1a;多媒体处理的瑞士军刀 前言 FFmpeg 是一个功能强大且跨平台的开源多媒体框架&#xff0c;广泛应用于音视频处理领域。 它由多个库和工具组成&#xff0c;能够处理各种音视频格式&#xff0c;涵盖编码、解码、转码、流处理等多种操作。 无论是专业视频编辑…

【深度分析】DeepSeek大模型技术解析:从架构到应用的全面探索

深度与创新&#xff1a;AI领域的革新者 DeepSeek&#xff0c;这个由幻方量化创立的人工智能公司推出的一系列AI模型&#xff0c;不仅在技术架构上展现出了前所未有的突破&#xff0c;更在应用领域中开启了无限可能的大门。从其混合专家架构&#xff08;MoE&#xff09;到多头潜…

python学opencv|读取图像(五十五)使用cv2.medianBlur()函数实现图像像素中值滤波处理

【1】引言 在前述学习过程中&#xff0c;已经探索了取平均值的形式进行图像滤波处理。 均值滤波的具体的执行对象是一个nXn的像素核&#xff0c;对这个像素核内所有像素点的BGR值取平均值&#xff0c;然后把这个平均的BGR值直接赋给像素核中心位置的核心像素点&#xff0c;由…

OpenAI 再战机器人领域,重组机器人团队

OpenAI重组机器人团队&#xff1f;大家是不是和小编一样&#xff0c;听到这个消息后&#xff0c;脑子里瞬间浮现出科幻电影里机器人满街跑的场景&#xff1f;今天咱们就来看看背后的故事吧~ 作为人工智能领域的领头羊&#xff0c;OpenAI一直以来都在探索和扩展AI技术的深度和广…

Turing Complete-1位开关

要求如下&#xff1a; 我的思考&#xff1a; 把输入1当作控制信号&#xff0c;把输入2当作输出信号。 通过非门和开关使输入2形成双通道输出&#xff0c; 通道一为输出输入2取反。 通道二为输出输入2本身。 通过输入1来控制两个通道的开闭。

树莓派pico入坑笔记,睡眠

关于树莓派pico和circuitpython的更多玩法&#xff0c;请看树莓派pico专栏 关于在 CircuitPython 中使用警报和浅/深度睡眠的更多信息&#xff0c;请参阅此学习指南。 树莓派pico支持浅睡眠和深度睡眠&#xff0c;其中深度睡眠唤醒后将从boot.py开始运行 支持按时间唤醒和引…

数据库 - Sqlserver - SQLEXPRESS、由Windows认证改为SQL Server Express认证进行连接 (sa登录)

本文讲SqlServer Express版本在登录的时候&#xff0c; 如何由Windows认证&#xff0c;修改为Sql Server Express认证。 目录 1&#xff0c;SqlServer Express的Windows认证 2&#xff0c;修改为混合认证 3&#xff0c;启用sa 用户 4&#xff0c;用sa 用户登录 下面是详细…

中间件漏洞之CVE-2024-53677

目录 什么是struts&#xff1f;CVE-2024-53677简介影响版本复现环境搭建漏洞利用修复 什么是struts&#xff1f; 在早期的 Java Web 开发中&#xff0c;代码往往混乱不堪&#xff0c;难以维护和扩展。比如&#xff0c;一个简单的用户登录功能&#xff0c;可能在不同的 Java 类…

Python玄学

过年期间无聊的看了看DY直播&#xff0c;也是迷上玄学了。突然想着为啥要自己掐指算&#xff0c;我这&#x1f437;脑哪记得到那么多东西啊。然后&#xff0c;就捣鼓捣鼓了一些玩意儿。留个纪念。 注&#xff1a;就是一个玄学推动学习&#xff0c;部分内容不必当真&#xff0c;…

16.1.STM32F407ZGT6-CAN基础概念

参考&#xff1a; https://blog.csdn.net/sunlight_vip/article/details/128639144 前言&#xff1a; 学习总结CAN的知识点&#xff1a; 1.can是什么&#xff0c;历史由来和背景 2.can的物理层&#xff0c;链路层 3.初始化的流程和关键点 4.波特率怎么设置 5.can id怎么过滤 6…

【论文笔记】Fast3R:前向并行muti-view重建方法

众所周知&#xff0c;DUSt3R只适合做稀疏视角重建&#xff0c;与sapnn3r的目的类似&#xff0c;这篇文章以并行的方法&#xff0c;扩展了DUSt3R在多视图重建中的能力。 abstract 多视角三维重建仍然是计算机视觉领域的核心挑战&#xff0c;尤其是在需要跨不同视角实现精确且可…

使用VCS对Verilog/System Verilog进行单步调试的步骤

Verilog单步调试&#xff1a; System Verilog进行单步调试的步骤如下&#xff1a; 1. 编译设计 使用-debug_all或-debug_pp选项编译设计&#xff0c;生成调试信息。 我的4个文件&#xff1a; 1.led.v module led(input clk,input rst_n,output reg led );reg [7:0] cnt;alwa…

[ESP32:Vscode+PlatformIO]新建工程 常用配置与设置

2025-1-29 一、新建工程 选择一个要创建工程文件夹的地方&#xff0c;在空白处鼠标右键选择通过Code打开 打开Vscode&#xff0c;点击platformIO图标&#xff0c;选择PIO Home下的open&#xff0c;最后点击new project 按照下图进行设置 第一个是工程文件夹的名称 第二个是…

如何使用 DeepSeek API 结合 VSCode 提升开发效率

引言 在当今的软件开发领域&#xff0c;API 的使用已经成为不可或缺的一部分。DeepSeek 是一个强大的 API 平台&#xff0c;提供了丰富的功能和数据&#xff0c;可以帮助开发者快速构建和优化应用程序。而 Visual Studio Code&#xff08;VSCode&#xff09;作为一款轻量级但功…

Flutter使用Flavor实现切换环境和多渠道打包

在Android开发中通常我们使用flavor进行多渠道打包&#xff0c;flutter开发中同样有这种方式&#xff0c;不过需要在原生中配置 具体方案其实flutter官网个了相关示例&#xff08;https://docs.flutter.dev/deployment/flavors&#xff09;,我这里记录一下自己的操作 Android …

OpenAI 实战进阶教程 - 第四节: 结合 Web 服务:构建 Flask API 网关

目标 学习将 OpenAI 接入 Web 应用&#xff0c;构建交互式 API 网关理解 Flask 框架的基本用法实现 GPT 模型的 API 集成并返回结果 内容与实操 一、环境准备 安装必要依赖&#xff1a; 打开终端或命令行&#xff0c;执行以下命令安装 Flask 和 OpenAI SDK&#xff1a; pip i…

Hot100之堆

我们的PriorityQueue默认为最小堆&#xff0c;堆顶总是为最小 215数组中的第K个最大元素 题目 思路解析 暴力解法&#xff08;不符合时间复杂度&#xff09; 题目要求我们找到「数组排序后的第 k 个最大的元素&#xff0c;而不是第 k 个不同的元素」。「数组排序后的第 k …

KNIME:开源 AI 数据科学

KNIME&#xff08;Konstanz Information Miner&#xff09;是一款开源且功能强大的数据科学平台&#xff0c;由德国康斯坦茨大学的软件工程师团队开发&#xff0c;自2004年推出以来&#xff0c;广泛应用于数据分析、数据挖掘、机器学习和可视化等领域。以下是对KNIME的深度介绍…

Office / WPS 公式、Mathtype 公式输入花体字、空心字

注&#xff1a;引文主要看注意事项。 1、Office / WPS 公式中字体转换 花体字 字体选择 “Eulid Math One” 空心字 字体选择 “Eulid Math Two” 2、Mathtype 公式输入花体字、空心字 2.1 直接输入 花体字 在 mathtype 中直接输入 \mathcal{L} L \Large \mathcal{L} L…