【LeetCode 刷题】回溯算法(5)-棋盘问题

news2025/2/4 21:03:40

此博客为《代码随想录》二叉树章节的学习笔记,主要内容为回溯算法棋盘问题相关的题目解析。

文章目录

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

51. N皇后

题目链接

class Solution:
    def solveNQueens(self, n: int) -> List[List[str]]:
        board = [['.' for _ in range(n)] for _ in range(n)]
        res = []

        def check(x: int, y: int) -> bool:
            for i in range(x):
                if board[i][y] == 'Q':  # 列
                    return False
                if y - (x - i) >= 0 and board[i][y-(x-i)] == 'Q':  # 45对角线
                    return False
                if y + (x - i) < n and board[i][y+(x-i)] == 'Q':  # -45对角线
                    return False
            return True
        
        def dfs(row: int) -> None:
            if row == n:
                res.append([''.join(row) for row in board])
                return
            for col in range(n):
                if check(row, col):
                    board[row][col] = 'Q'
                    dfs(row + 1)
                    board[row][col] = '.'
        
        dfs(0)
        return res
  • dfs 函数的参数为行号,即“第 row 行选哪一列放皇后”构成递归树的一层
  • 判断合法性时,不需要判断行是否合法,因为上述解法递归的逻辑即为每一行选择一列去放皇后,所以行约束肯定满足;且判断时只需要判断当前行 x 以上的合法性,因为下面的行还没有放皇后,肯定不会冲突

37. 解数独

题目链接

class Solution:
    def solveSudoku(self, board: List[List[str]]) -> None:
        """
        Do not return anything, modify board in-place instead.
        """
        def check(x: int, y: int, num: str) -> bool:
            for i in range(9):
                if board[i][y] == num:
                    return False
            for i in range(9):
                if board[x][i] == num:
                    return False
            row_s, col_s = x // 3 * 3, y // 3 * 3
            for i in range(3):
                for j in range(3):
                    if board[row_s+i][col_s+j] == num:
                        return False
            return True

        def dfs() -> bool:
            for i in range(9):
                for j in range(9):
                    if board[i][j] == '.':
                        for num in range(1, 10):
                            if check(i, j, str(num)):
                                board[i][j] = str(num)
                                if dfs(): return True
                                board[i][j] = '.'
                        return False
            return True
        
        dfs()
        return
  • 数独的 check 函数需要检查整个棋盘,而非当前行列之前的内容
  • 当找到一个解时,直接返回 True,之前的递归也不再进行回溯;如果当前位置 1-9 全部遍历也没找到解,则返回 False

332.重新安排行程

题目链接

class Solution:
    def findItinerary(self, tickets: List[List[str]]) -> List[str]:
        tickets = sorted(tickets, key=lambda x: (x[0], x[1]))
        graph = {}
        for u, v in tickets:
            if u in graph:
                graph[u].append(v)
            else:
                graph[u] = [v]
        path = ['JFK']
        
        def dfs(u, num):
            if num == 0:
                return True
            if u not in graph or not graph[u]:
                return False
            aims = graph[u].copy()
            for v in aims:
                graph[u].pop(graph[u].index(v))
                path.append(v)
                if dfs(v, num - 1):
                    return True
                path.pop()
                graph[u].append(v)
            return False
    
        dfs("JFK", len(tickets))
        return path
  • dfs 函数的参数分别为:当前站点,以及还有几站到达终点
  • 首先需要将 tickets 转换为有向图的形式,之后遍历当前点所有可能的下一站点列表,每处理一个站点,从原始列表中移除,回溯时再将站点添加回列表
  • 由于最开始按照字典序升序排列,因此一旦找到一条合法行程,即为满足题目要求的字典序最小的行程,递归函数即可返回;如果当前处理的站点不存在合法的下一站,则回溯。

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

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

相关文章

算法题(48):反转链表

审题&#xff1a; 需要我们将链表反转并返回头结点地址 思路&#xff1a; 一般在面试中&#xff0c;涉及链表的题会主要考察链表的指向改变&#xff0c;所以一般不会允许我们改变节点val值。 这里是单向链表&#xff0c;如果要把指向反过来则需要同时知道前中后三个节点&#x…

梯度、梯度下降、最小二乘法

在求解机器学习算法的模型参数&#xff0c;即无约束优化问题时&#xff0c;梯度下降是最常采用的方法之一&#xff0c;另一种常用的方法是最小二乘法。 1. 梯度和梯度下降 在微积分里面&#xff0c;对多元函数的参数求∂偏导数&#xff0c;把求得的各个参数的偏导数以向量的形式…

独立开发者小程序开发变现思路

随着移动互联网的发展&#xff0c;小程序已成为许多独立开发者展示才能和实现收入的重要平台。作为一种轻量级的应用形态&#xff0c;小程序具有开发成本低、用户体验好、传播效率高等优势&#xff0c;为独立开发者提供了多种变现方式。然而&#xff0c;要想实现真正的盈利&…

软件测试 - 概念篇

目录 1. 需求 1.1 用户需求 1.2 软件需求 2. 开发模型 2.1 软件的生命周期 2.2 常见开发模型 2.2.1 瀑布模型 2.2.2 螺旋模型 1. 需求 对于软件开发而言, 需求分为以下两种: 用户需求软件需求 1.1 用户需求 用户需求, 就是用户提出的需求, 没有经过合理的评估, 通常…

使用SpringBoot发送邮件|解决了部署时连接超时的bug|网易163|2025

使用SpringBoot发送邮件 文章目录 使用SpringBoot发送邮件1. 获取网易邮箱服务的授权码2. 初始化项目maven部分web部分 3. 发送邮件填写配置EmailSendService [已解决]部署时连接超时附&#xff1a;Docker脚本Dockerfile创建镜像启动容器 1. 获取网易邮箱服务的授权码 温馨提示…

基于springboot+vue的航空散货调度系统

开发语言&#xff1a;Java框架&#xff1a;springbootJDK版本&#xff1a;JDK1.8服务器&#xff1a;tomcat7数据库&#xff1a;mysql 5.7&#xff08;一定要5.7版本&#xff09;数据库工具&#xff1a;Navicat11开发软件&#xff1a;eclipse/myeclipse/ideaMaven包&#xff1a;…

[MRCTF2020]Ez_bypass1(md5绕过)

[MRCTF2020]Ez_bypass1(md5绕过) ​​ 这道题就是要绕过md5强类型比较&#xff0c;但是本身又不相等&#xff1a; md5无法处理数组&#xff0c;如果传入的是数组进行md5加密&#xff0c;会直接放回NULL&#xff0c;两个NuLL相比较会等于true&#xff1b; 所以?id[]1&gg…

MATLAB实现多种群遗传算法

多种群遗传算法&#xff08;MPGA, Multi-Population Genetic Algorithm&#xff09;是一种改进的遗传算法&#xff0c;它通过将种群分成多个子种群并在不同的子种群之间进行交叉和交换&#xff0c;旨在提高全局搜索能力并避免早期收敛。下面是多种群遗传算法的主要步骤和流程&a…

强化学习笔记(5)——PPO

PPO视频课程来源 首先理解采样期望的转换 变量x在p(x)分布下&#xff0c;函数f(x)的期望 等于f(x)乘以对应出现概率p(x)的累加 经过转换后变成 x在q(x)分布下&#xff0c;f(x)*p(x)/q(x) 的期望。 起因是&#xff1a;求最大化回报的期望&#xff0c;所以对ceta求梯度 具体举例…

【MATLAB例程】TOA和AOA混合的高精度定位程序,适用于三维、N锚点的情况

代码实现了一个基于到达角&#xff08;AOA&#xff09;和到达时间&#xff08;TOA&#xff09;混合定位的例程。该算法能够根据不同基站接收到的信号信息&#xff0c;自适应地计算目标的位置&#xff0c;适用于多个基站的场景 文章目录 主要功能代码结构运行结果程序代码 主要功…

使用Pygame制作“青蛙过河”游戏

本篇博客将演示如何使用 Python Pygame 从零开始编写一款 Frogger 风格的小游戏。Frogger 是一款早期街机经典&#xff0c;玩家需要帮助青蛙穿越车水马龙的马路到达对岸。本示例提供了一个精简原型&#xff0c;包含角色移动、汽车生成与移动、碰撞检测、胜利条件等关键点。希望…

深度解读 Docker Swarm

一、引言 随着业务规模的不断扩大和应用复杂度的增加,容器集群管理的需求应运而生。如何有效地管理和调度大量的容器,确保应用的高可用性、弹性伸缩和资源的合理分配,成为了亟待解决的问题。Docker Swarm 作为 Docker 官方推出的容器集群管理工具,正是在这样的背景下崭露头…

8、面向对象:类、封装、构造方法

一、类 1、定义 类&#xff1a;对现实世界中事物的抽象。Student 对象&#xff1a;现实世界中具体的个体。张三、李四 这些具体的学生 面向对象的特征&#xff1a;抽象、封装、继承、多态 OOP: Object Oriented Programming&#xff08;面向对象编程&#xff09; 类和对象…

STM32 旋转编码器

旋转编码器简介 旋转编码器&#xff1a;用来测量位置、速度或旋转方向的装置&#xff0c;当其旋转轴旋转时&#xff0c;其输出端可以输出与旋转速度和方向对应的方波信号&#xff0c;读取方波信号的频率和相位信息即可得知旋转轴的速度和方向 类型&#xff1a;机械触点式/霍尔传…

git基础使用--4---git分支和使用

文章目录 git基础使用--4---git分支和使用1. 按顺序看2. 什么是分支3. 分支的基本操作4. 分支的基本操作4.1 查看分支4.2 创建分支4.3 切换分支4.4 合并冲突 git基础使用–4—git分支和使用 1. 按顺序看 -git基础使用–1–版本控制的基本概念 -git基础使用–2–gti的基本概念…

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

目录 前置小试牛刀回归经典举一反三总结 前置 【算法】回溯算法专题① ——子集型回溯 python 【算法】回溯算法专题② ——组合型回溯 剪枝 python 小试牛刀 全排列 https://leetcode.cn/problems/permutations/description/ 给定一个不含重复数字的数组 nums &#xff0c;返…

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;由…