算法套路十二——回溯法之排列型回溯

news/2024/7/20 22:57:51 标签: 算法, leetcode, 深度优先

算法套路十二——回溯法之排列型回溯

  • 该节是在第十节回溯法之子集型回溯的基础上进行描写,组合型回溯会在子集型回溯的基础上判断所选子集是否符合组合要求, 故请首先阅读第十节算法套路十——回溯法之子集型回溯

算法示例一:leetcode.cn/problems/permutations/">LeetCode46. 全排列

给定一个不含重复数字的数组 nums ,返回其 所有可能的全排列 。你可以 按任意顺序 返回答案。在这里插入图片描述

在这里插入图片描述
相比子集型回溯,排序型回溯的区别就是在选择相同子集时不会判断为重复,而是不同的排列,因此我们从答案的角度出发,考虑每次选哪一个数,且由于选择顺序不同排列也不同,故在递归时不用考虑要使后选的元素大于当前选的元素,那我们如何判断是否选择,可以使用on_path数组,来记录数组第i个元素是否被选择,且要在递归完成后回溯

class Solution:
    def permute(self, nums: List[int]) -> List[List[int]]:
        n=len(nums)
        ans=[]
        path=[]
        on_path=[False]*n
        def dfs(i:int)-> None:
            if i==n:
                ans.append(path.copy())
                return
            for j in range(0,n):
                if on_path[j]==False:
                    on_path[j]=True
                    path.append(nums[j])
                    dfs(i+1)
                    on_path[j]=False
                    path.pop()
        dfs(0)
        return ans

算法示例二:leetcode.cn/problems/n-queens/">LeetCode51. N 皇后

按照国际象棋的规则,皇后可以攻击与之处在同一行或同一列或同一斜线上的棋子。
n 皇后问题 研究的是如何将 n 个皇后放置在 n×n 的棋盘上,并且使皇后彼此之间不能相互攻击。
给你一个整数 n ,返回所有不同的 n 皇后问题 的解决方案。
每一种解法包含一个不同的 n 皇后问题 的棋子放置方案,该方案中 ‘Q’ 和 ‘.’ 分别代表了皇后和空位。在这里插入图片描述

本题是一道回溯法的经典题,第一次做时可能感觉难,认为要求很多,但如果搞懂题目要求并能使用回溯就会发现很简单。题目即要求行i、列j、左对角线值即i-j,右对角线即i+j不能重复

  • 用on_path记录当前列数是否已经被占据,
  • 用inclined_left集合来记录i-j的值来判断左对角线是否已经被占据,i-j相同即在同一左对角线
  • 用inclined_right集合来记录i-j的值来判断左对角线是否已经被占据,i+j相同即在同一右对角线

之后我们从答案的角度来对每一行应该选择哪一列来放皇后进行枚举,如果满足当前列数、左对角线、右对角线都没有占据,那么就记录、递归、回溯三步直接进行枚举

class Solution:
    def solveNQueens(self, n: int) -> List[List[str]]:
        path=[]
        ans=[]
        #列数
        on_path=[False]*n
        #左对角线,i-j相同即同一左对角线
        inclined_left=set()
        #右对角线,i+j相同即同一右对角线
        inclined_right=set()
        def dfs(i:int)->None:
            if i==n:
                ans.append(['.' * c + 'Q' + '.' * (n - 1 - c) for c in path])
                return
            #i行j列
            for j in range(0,n):
                if on_path[j]==False and i-j not in inclined_left and i+j not in inclined_right:
                    path.append(j)
                    on_path[j]=True
                    inclined_left.add(i-j)
                    inclined_right.add(j+i)
                    dfs(i+1)
                    path.pop()
                    on_path[j]=False
                    inclined_left.remove(i-j)
                    inclined_right.remove(j+i)
        dfs(0)
        return ans    
            

http://www.niftyadmin.cn/n/251190.html

相关文章

C++ 互斥锁原理以及实际使用介绍

兄弟姐妹们,我又回来了,今天带来实际开发中都需要使用的互斥锁的内容,主要聊一聊如何使用互斥锁以及都有哪几种方式实现互斥锁。实现互斥,可以有以下几种方式:互斥量(Mutex)、递归互斥量&#x…

synchronized原理:

vm中每个对象都会有一个监视器Monitor,监视器和对象一起创建、销毁。监视器相当于一个用来监视这些线程进入的特殊房间,其义务是保证(同一时间)只有一个线程可以访问被保护的临界区代码块。每一个锁都对应一个monitor对象&#xf…

掌握虚拟专用网络配置

目录 一、防火墙的IPSEC VPN 二、DSVPN 一、防火墙的IPSEC VPN 总体拓扑如下:实现PC间的加密通信。 FW1的配置:划分接口配置地址。 定义感兴趣流: 注:什么是感兴趣流?答:感兴趣流是VPN的术语&#xff0…

数据结构和算法面试题系列-栈

0 概述 栈作为一种基本的数据结构,在很多地方有运用,比如函数递归,前后缀表达式转换等。本文会用C数组来实现栈结构(使用链表实现可以参见链表那一节,使用头插法构建链表即可),并对常见的几个跟栈相关的面试题进行分析…

Python入门到精通13天(global和nonlocal关键字的使用)

global和nonlocal关键字的使用 作用域global关键字的使用nonlocal关键字的使用 作用域 在Python中变量的作用域由其代码块决定,在代码块中定义的的变量和函数属于局部作用域;在函数中定义的变量和函数属于函数作用域;在模块中定义的变量和函…

Java面试题--MySQL索引

一. 索引介绍 MySQL的索引是一种数据结构,它可以帮助MySQL快速定位需要访问的记录。索引可类比于一本书的目录,通过它可以快速找到某个特定的记录。 MySQL支持多种类型的索引,每种索引都有其优势和局限性,常用的包括&#xff1a…

Science | 华盛顿大学Baker团队提出AI新范式设计全新蛋白复合物

蛋白质的结构形态和生物学功能是由氨基酸序列决定的。 人工蛋白质设计的目标就是创造可以折叠成特定结构以实现特定功能的新型氨基酸序列。 当然,这并不是一个简单的问题,因为它需要了解蛋白质如何在细胞中折叠,而这一过程在很大程度上仍不为…

【方法一:二分+字符串哈希 优化】【dp——取不取问题-背包】最长公共子串【上海交通大学考研机试题】

最长公共子串 二分方法字符串哈希的复习字符串哈希 如何理解 二分代码 dp方法字符串str1中以第i个字符为结尾的子串 与字符串str2中以第i个字符为结尾的子串的连续公共子串 二维一维优化 二分方法 由于这个题是要求求子串,而子串是连续的一段,所以用二分…