数据结构与算法之递归: LeetCode 46. 全排列 (Ts, Py, Go版)

InSAR图像配准:从像素级到亚像素级的精度提升策略 本文深入探讨了InSAR图像配准技术,从像素级到亚像素级的精度提升策略。通过分析最大频谱法和相干系数法的适用场景,结合频域补零插值和四叉树分块等高级技术,实现1/8像素级的高精度配准。文章还提供了实用的精度验证方法和常见问题排查指南,为InSAR数据处理提供全面解决方案。 阅读详情

全排列

  • https://leetcode.cn/problems/permutations/

描述

  • 给定一个不含重复数字的数组 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 中的所有整数 互不相同

Typescript 版算法实现


1 )回溯1: 基于数组

function permute(nums: number[]): number[][] {
    const res: number[][] = [];
    // 回溯函数
    const backtrack = (path: number[]) => {
        // 满足当前条件
        if(path.length === nums.length) {
            res.push(path);
            return;
        }
        // 遍历
        for(let i = 0; i < nums.length; i++) {
            if(path.includes(nums[i])) continue;
            backtrack(path.concat(nums[i]));
        }
    }
    backtrack([]);
    return res;
}
  • 时间复杂度:O(n*n!)
    • 假设输入数组的长度为 n
    • 遍历每个元素的时间复杂度为 O(n)
    • 对于每个元素,都会进行递归调,假设数组中有 n 个不同的元素
    • 那么对于每个元素,都会有 n-1 个可能的选择,然后对于每个选择,又会有 n-2 个可能的选择,以此类推
    • 因此,递归的时间复杂度可以表示为 O(n!)。
    • 在每一层递归中,都会进行一次包含操作(includes),其时间复杂度为 O(n)。
    • 综合考虑,这段代码的时间复杂度为 O(n * n!),其中 n 表示输入数组的长度。
    • 需要注意的是,这里的时间复杂度分析基于平均情况。
    • 在最坏情况下,全排列的数量是 n!,因此在最坏情况下,时间复杂度为 O(n * n!)
    • 注意: n的阶乘公式: n! = 1*2*3*...*(n-1)*n
  • 空间复杂度:O(n)
    • 递归,堆栈,不是常量,是线性增长的
    • 是递归的层数

2 )回溯2: 基于交换

function permute(nums: number[]): number[][] {
    const res: number[][] = [];
    const backtrack = function(start: number) {
        if (start === nums.length - 1) {
            res.push([...nums]);
            return;
        }
        for (let i: number = start; i < nums.length; i++) {
            [nums[i], nums[start]] = [nums[start], nums[i]]; // 交换
            backtrack(start + 1); // 下一个数
            [nums[i], nums[start]] = [nums[start], nums[i]]; // 交换撤销
        }
    }
    backtrack(0); // 从 0 开始
    return res;
};
  • 这个问题可以看作有 n 个排列成一行的空格,我们需要从左往右依此填入题目给定的 n 个数,每个数只能使用一次
  • 那么很直接的可以想到一种穷举的算法,即从左往右每一个位置都依此尝试填入一个数
  • 看能不能填完这 n 个空格,在程序中我们可以用「回溯法」来模拟这个过程
  • 时间复杂度:O(n*n!),其中 n 为序列的长度
  • 空间复杂度:O(n)

回溯算法、递归和深度优先遍历之间的关系

  • 它们通常在算法中一起使用,因为回溯算法通常使用递归来实现,并且常常涉及到深度优先遍历的思想。

  • 回溯算法与递归

    • 回溯算法是一种渐进式寻找并构建问题解决方案的策略。
    • 在回溯算法中,通常通过递归的方式来尝试所有可能的情况。
    • 当找到一个可能的解决方案时,它会继续探索下去,如果发现不符合条件,就会回溯到上一个状态,尝试其他可能的情况。
    • 因此,回溯算法通常使用递归来实现,因为递归天然地适合于处理这种尝试所有可能情况的问题。
  • 回溯算法与深度优先遍历(DFS)

    • 回溯算法通常使用深度优先遍历的思想。
    • 在回溯算法中,我们会尝试一条路走到底,直到无法再继续下去,然后回溯到上一个状态,尝试其他的可能性。
    • 这与深度优先遍历的思想是一致的,深度优先遍历也是尽可能深地搜索树的分支,直到无法再继续为止
    • 然后回溯到上一个节点,继续搜索其他分支
  • 因此,回溯算法通常使用递归来实现,并且其思想与深度优先遍历密切相关。

  • 在许多情况下,回溯算法可以被视为一种特殊的深度优先遍历。

Python3 版算法实现


1 ) 方案1

class Solution:
    def permute(self, nums: List[int]) -> List[List[int]]:
        res = []

        def backtrack(path: list[int]):
            # 满足当前条件
            if len(path) == len(nums):
                res.append(path)
                return
            # 遍历
            for i in range(len(nums)):
                if nums[i] in path:
                    continue
                backtrack(path + [nums[i]])

        backtrack([])
        return res

2 ) 方案2

class Solution:
    def permute(self, nums: List[int]) -> List[List[int]]:
        res = []

        def backtrack(start: int):
            if start == len(nums) - 1:
                res.append(nums[:])
                return
            for i in range(start, len(nums)):
                # 交换
                nums[i], nums[start] = nums[start], nums[i]
                # 下一个数
                backtrack(start + 1)
                # 交换撤销
                nums[i], nums[start] = nums[start], nums[i]

        backtrack(0)  # 从 0 开始
        return res

Golang 版算法实现


1 ) 方案1

func permute(nums []int) [][]int {
	var res [][]int

	// 回溯函数
	var backtrack func(path []int)
	backtrack = func(path []int) {
		// 满足当前条件
		if len(path) == len(nums) {
			// 创建一个新的切片,防止后续修改影响结果
			newPath := make([]int, len(path))
			copy(newPath, path)
			res = append(res, newPath)
			return
		}
		// 遍历
		for i := 0; i < len(nums); i++ {
			if contains(path, nums[i]) {
				continue
			}
			backtrack(append(path, nums[i]))
		}
	}

	backtrack([]int{})
	return res
}

// contains 检查切片中是否包含某个元素
func contains(slice []int, val int) bool {
	for _, v := range slice {
		if v == val {
			return true
		}
	}
	return false
}

2 ) 方案2

// permute 生成所有排列
func permute(nums []int) [][]int {
	var res [][]int

	// 回溯函数
	var backtrack func(start int)
	backtrack = func(start int) {
		if start == len(nums)-1 {
			// 创建一个新的切片,防止后续修改影响结果
			newNums := make([]int, len(nums))
			copy(newNums, nums)
			res = append(res, newNums)
			return
		}
		for i := start; i < len(nums); i++ {
			// 交换
			nums[i], nums[start] = nums[start], nums[i]
			// 下一个数
			backtrack(start + 1)
			// 交换撤销
			nums[i], nums[start] = nums[start], nums[i]
		}
	}

	backtrack(0) // 从 0 开始
	return res
}
基于Simulink的电机功率因数校正仿真 PF=SP​=视在功率有功功率​=cosϕ⋅Irms​I1​​(非正弦时)位移因数(cosϕ):基波电压电流相位差畸变因数(I1​/Irms​):谐波导致电流有效值增大本文带你完成了电机系统功率因数校正的Simulink仿真,实现了:✅ 理解了低功率因数的成因与危害✅ 搭建了无PFC、无源PFC、有源PFC三种对比模型✅ 掌握了Vienna整流器建模与dq解耦控制方法✅ 实现了PF与THD的自动计算与评估✅ 验证了有源PFC在PF、THD、稳定性上的全面优势。 阅读详情

相关推荐

【电子元件篇】MOSFET场效应管作用、选型和测量指南-超简单解读

场效应管是一种电压控制型半导体器件,相比三极管具有输入阻抗高、噪声小、功耗低等优势。主要分为结型和绝缘栅型两大类,后者又可分为耗尽型和增强型MOS管。场效应管通过栅极电压控制漏极电流,具有转移特性和输出特性两大静态特性,以及快速的开关特性。其关键参数包括饱和漏源电流、夹断电压、跨导等,应用场景涵盖信号放大、恒流源、阻抗变换等领域。使用时需根据电路需求选择合适类型,如结型管适合一般放大,功率MOSFET适合高压大电流场合。检测时可用万用表电阻档初步判断好坏和放大能力。

2301_81299416的博客 2542

基于python的leetcode算法介绍之递归

该文章介绍了什么是递归,并通过python的方式,在leetcode中找寻了几道真题作为参考,为大家呈现。

盼盼的博客 1238

MATLAB小白也能搞定!BCT脑网络分析工具箱安装与入门指南

本文为零基础用户提供了一份详尽的BCT脑网络分析工具箱安装与入门指南。从MATLAB环境配置、BCT工具箱下载与路径添加,到连接矩阵构建、节点度与聚类系数等基础指标计算,手把手带领神经科学研究者跨越编程门槛,快速掌握脑影像数据分析的核心流程。

threejs5artist的博客 1092

Go实现字符串全排列详解递归

人生就是一场游戏,我们不停的打怪通关,有的时候这个怪物是自己。————陌无崖不忘初心,砥砺前行作者 | 陌无崖转载请联系授权题目要求输入一个字符串,打印出该字符串中字符的所有排列,例...

鱼尾九八 1666

Ansys Circuit新手必看:IBIS模型导入时,Pin Import和Buffer Import到底怎么选?

本文详细解析了Ansys Circuit中IBIS模型导入时Pin Import与Buffer Import的选择策略,帮助SI/PI工程师根据仿真需求做出正确决策。通过对比两种方式的特性差异和应用场景,提供实用的选择指南和性能优化建议,提升信号完整性仿真效率。

weixin_26846533的博客 262

Silvaco TCAD实战 | SiC MOSFET工艺仿真与关键参数DOE分析

本文详细介绍了使用Silvaco TCAD进行SiC MOSFET工艺仿真与关键参数DOE分析的实战方法。通过外延生长建模、离子注入工艺调试等步骤,结合DOE分析优化器件性能,帮助工程师在设计阶段预判电学特性,提升产品可靠性。文章还分享了网格划分、界面态建模等实用技巧,助力实现从仿真到产品的闭环验证。

weixin_30235225的博客 509

leetcode - 递归

目录 98.验证搜索二叉树 22.括号生成 100.相同的树 101.对称二叉树 104.树的最大深度 108.将有序数组转换成搜索二叉树 110.平衡二叉树 111.二叉树的最小深度 112.路径总和 226.翻转二叉树 98.验证搜索二叉树 给定一个二叉树,判断其是否是一个有效的二叉搜索树。 假设一个二叉搜索树具有如下特征: 节点的左子树只包含小于当前节点的数。 ...

mike_jun的博客 835

RT-Thread实战:手把手教你用STM32F04ZGT6通过SPI驱动BMI088(附完整工程)

本文详细介绍了如何使用RT-Thread操作系统在STM32F04ZGT6上通过SPI接口驱动BMI088高性能6轴惯性传感器(包含陀螺仪和加速度计)。从硬件连接到软件配置,再到数据采集与处理,提供了完整的开发指南和优化技巧,帮助开发者快速实现精确的姿态测量功能。

kappa的博客 237

LeetCode21——————合并两个有序链表 python (递归非递归)

如题 将两个有序链表合并为一个新的有序链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。 示例: 输入: 1-&gt; 2-&gt; 4,1 -&gt; 3-&gt; 4 输出: 1-&gt; 1-&gt; 2-&gt; 3-&gt; 4-&gt; 4 思路 : 1. 若都为空则直接返回空 2.若一个为空另一个不为,则直接返回另一个非空 3.非递归:建立一个新头结点...

bibigod的博客 915

海康VisionMaster使用学习笔记7-Group模块

光标需放在[]中选择循环索引,循环索引用于实现依次检测10个匹配框的顶点,若不订阅,模块会循环检测同一个匹配框。可以看到绿色是它的边缘点.为方便查看顶点,将边缘点设置为不可见。循环使能打开,开始值设为0,循环结束值设为快速匹配的匹配个数。回到上一层,点击Group工具的设置图标,圆拟合的点设置为Group工具输出的点集。图像输入源选择Group的图像输入源。区域选择Group的快速匹配的匹配框。添加订阅到Group内部的顶点检测。对匹配框区域进行顶点检测。用于定位匹配框中的顶点。添加快速匹配的匹配框。

风凌的博客 4181

国科大——形式语言与自动机理论(0812课程)——作业

此次作业题考察,包括但不限于有限自动机、无限自动机、正则文法、正则表达式以及正则语言的性质,题考查下推自动机相关的知识,题考查图灵机相关的知识。此课程建议本科学习过课程的同学选修,成绩占比:考试100%。此课程虽然留有作业,但可做也可不做,且不考勤。

qq_54145399的博客 707

递归--Leetcode(python)

至少有K个重复字符的最长子串 找到给定字符串(由小写字符组成)中的最长子串 T , 要求 T 中的每一字符出现次数都不少于 k 。输出 T 的长度。 示例 1: 输入: s = “aaabb”, k = 3 输出: 3 最长子串为 “aaa” ,其中 ‘a’ 重复了 3 次。 示例 2: 输入: s = “ababbc”, k = 2 输出: 5 最长子串为 “ababb” ,其中 ‘a’ 重复了 2 次, ‘b’ 重复了 3 次。 解法 看题目有点像用动态规划的方法来做,但是并没有好方法,而是用递归。 首

扣扣biubiubiu~ 1277

YOLO11涨点优化:Loss魔改 | WIoU (Wise-IoU) v3版本全面替换,基于动态非单调聚焦机制,让模型更聪明地学习

YOLOv11目标检测中的WIoU v3损失函数改进 本文探讨了YOLOv11目标检测模型中CIoU损失函数的局限性,并提出了WIoU v3改进方案。关键发现包括: CIoU的缺陷:在低质量样本(小目标/遮挡目标)上过度惩罚,导致模型优化方向偏离,小目标AP往往比大目标低30%左右。 WIoU v3的创新: 动态非单调聚焦机制:根据样本"离群度"智能分配梯度 让模型重点优化中等质量样本,减少对低质量样本的无效关注 采用指数移动平均来自适应调整质量评判标准 实际效果:WIoU v3在保持大

2601_95807009的博客 425

LeetCode 46. 全排列题解:回溯算法(DFS)深度剖析与多语言实现

本文基于开源仓库 doocs/leetcode 中 [46. 全排列](https://link.gitcode.com/i/e3b3eb5f84df38a9e57b18a5680bc889) 的题解文档,系统讲解“不含重复数字数组的全排列”这一经典回溯问题:从题目约束出发推导算法选择,深入拆解 `dfs(i)` 按位填数的深度优先搜索流程,并完整呈现仓库中 Python3、Java、C++、Go

gitblog_01104的博客 195

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

STM32F407中文手册

STM32f407中文手册 本参考手册面向应用开发人员,提供有关使用 STM32F405xx/07xx、STM32F415xx/17xx、 STM32F42xxx 和 STM32F43xxx 微控制器存储器与外设的完整信息。STM32F405xx/07xx、STM32F415xx/17xx、STM32F42xxx 和 STM32F43xxx 构成一个微 控制器系列,各产品具有不同的存储器大小、封装和外设。有关订购信息以及器件的机械与电气特性,请参见数据手册。有关 ARM Cortex™-M4F 内核的信息,请参见《Cortex™-M4F 技术参考手册》。

LeetCode 46. 全排列(Permutations)题解:DFS 回溯法原理与 8 种语言实现详解

> 本文基于 doocs/leetcode 开源题解仓库中 [0046.Permutations 题解文档](https://link.gitcode.com/i/01b66eadc80d4a0203aa26b21d1965e7)(英文版见 [README_EN.md](https://link.gitcode.com/i/e97271c975eb56c889c9c898a38aa1d3))展开,

gitblog_00309的博客 386

android 蓝牙通讯demo

android 下蓝牙通讯demo,实现了发现蓝牙,使能蓝牙,通过蓝牙发送消息。

LeetCode 47. 全排列 II:排序 + 回溯剪枝去重的多语言解法详解

> 本文以 doocs/leetcode 仓库中 [0047.Permutations II 题解](https://link.gitcode.com/i/397a3832f560623fdd2b446bf75c6118) 为主体,系统讲解"可含重复数字的序列如何生成不重复全排列"这一经典回溯问题:先排序让重复数字相邻,再通过一条剪枝条件让"同一层中每种值只被选择一次",从而在搜索源头去掉重复分支

gitblog_00819的博客 141

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

LeetCode 47. 全排列 II(Permutations II):排序 + 回溯去重的完整解法指南

本文基于 doocs/leetcode 开源题解仓库中 [0047.Permutations II 题解文档](https://link.gitcode.com/i/cfd5b525dc89ae7e53c55b0e4dc64385) 展开,系统讲解如何在包含重复数字的数组中生成**所有不重复的全排列**。文章覆盖问题描述、排序 + 回溯算法的完整推导、去重条件的精妙设计、时间复杂度分析,以及 Py

gitblog_00256的博客 154

Hello 算法回溯算法章节练习精解:状态回退、剪枝策略与全排列实现

本文以《Hello 算法》(hello-algo)仓库中回溯算法章节的章末练习([日文版原文档](https://link.gitcode.com/i/6b7ace90a611eef743d70de66792486e),其内容与[中文版练习](https://link.gitcode.com/i/bfc9ac0c9fb560993e05048fed437ed1)同步)为骨架,逐题拆解其背后的原理,

gitblog_00870的博客 608

(爆)重写目前做过的81道LeetCode题目

从6月份我的Leetcode计划两个月以来,明显的感觉到了Python熟练度有所提升,这两个月的时间,断断续续做了大概100道题,在博客上目前记录的有82道,有些数据结构和算法的题目,包括一些技巧其实还不是很熟练。对于应届生来说,算法基础还是最重要的一部分。 同时我不太满足于仅有的Python水平的提升,并不是贪多,而是觉得语言是相通的,Python仍是我接触很多语言以来最喜欢的语言,我也想...

eswang的优快云博客 598

Notepad-- ndd:面向中文开发者的免费跨平台文本编辑与文件对比完整指南

Notepad--(简称 ndd)是一款免费开源文本编辑器,支持 Windows、Linux、macOS 与国产 UOS,主打中文编码转换、文件对比和全目录查找替换。文件经常跨系统跑,它就适合你。 ## 🚀 先跑起来 最短路径,三步搞定: 1. 到项目 release 页下载对应系统的预编译包,装好直接运行,无需额外配置。 2. 想自己编译?只依赖 Qt5,一条命令克隆并构建: ```b

gitblog_00821的博客 585

KMS_VL_ALL_AIO 完整教程:一条命令激活 Windows 11 与 Office 2024,每周自动续期

重装完 Windows,桌面右下角"激活 Windows"的水印去不掉,打开 Office 又提示授权无效。单文件脚本 KMS_VL_ALL_AIO 一次运行就能完成 Windows 11 和 Office 2024 的 KMS 激活,之后按周自动续期,不用找密钥、不用记到期时间。 ## 60 秒上手:从克隆到激活完成 1. 命令行执行 `git clone https://gitcode.c

gitblog_00518的博客 225

LeetCode 60. 排列序列(Permutation Sequence)详解:阶乘分块枚举法(doocs/leetcode 题解精读)

本文以 doocs/leetcode 仓库中 [0060.Permutation Sequence 的官方题解](https://link.gitcode.com/i/8f57c16615012f84f26c36370a3cf396) 为核心,系统讲解「给定 n 与 k,直接求出第 k 个字典序排列」这一 Hard 级别经典题:从朴素全排列枚举的局限出发,推导出利用阶乘块大小逐位定位数字的 O(n

gitblog_01041的博客 189

剑指 Offer 46「把数字翻译成字符串」:记忆化搜索与动态规划题解详解

**导读**:本文基于 doocs/leetcode 仓库中《剑指 Offer(第 2 版)》面试题 46 的官方题解,深入讲解「数字 → 字母」翻译计数问题。你将掌握如何将问题抽象为带条件的斐波那契递推,并对比「自顶向下记忆化搜索」与「自底向上动态规划」两种实现,最终拿到 Python、Java、C++、Go、TypeScript、JavaScript、Rust、C#、Swift 等多语言可直接

gitblog_00658的博客 195

Hello 算法最小路径和实战:暴力搜索、记忆化搜索到动态规划的四步递进与可视化调试

本篇技术指南以《Hello 算法》仓库中的"最小路径和"(Min Path Sum)问题为主线,完整讲解动态规划(DP)的标准化求解流程:如何判断一个最优化问题适合用 DP 求解、如何定义状态与构建 dp 表、如何推导状态转移方程,并给出"暴力搜索 → 记忆化搜索 → 动态规划 → 空间优化"四种层层递进的实现方案及其复杂度对比。读完本文,你将掌握一套可复用的二维网格类 DP 问题分析范式,并能借

gitblog_00466的博客 187

二叉树最大深度(递归实现python)---LeetCode

# Definition for a binary tree node. # class TreeNode: # def __init__(self, x): # self.val = x # self.left = None # self.right = None class Solution: def maxDepth(sel...

Printfsome的博客 974

leetcode 206 Reserve Linked List(反转链表) python3 递归&迭代思路

# Definition for singly-linked list. # class ListNode: # def __init__(self, x): # self.val = x # self.next = None class Solution: def reverseList(self, head, prev = None): ...

Jasmine_dream 1178
上一篇: AIGC: 关于ChatGPT中的一些缺陷和解决之道
下一篇: 数据结构与算法之递归: LeetCode 78. 子集 (Ts, Py, Go版)
Wang's Blog
博客等级 码龄12年 7438粉丝 2421原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Wang's Blog

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值