46. /47.全排列Ⅰ/Ⅱ(中)

46.题目

  • 给定一个不含重复数字的数组 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]]

题解:回溯

python

class Solution:
    def permute(self, nums: List[int]) -> List[List[int]]:
        #nums是选择列表
        def backtrack(nums: List[int], track: List[int], res: List[List[int]]):
            if len(track) == len(nums):#触发结束条件:nums中的元素全都在track中出现
                res.append(track[:])  # 将路径加入结果
                return
            for i in range(len(nums)):
                if nums[i] in track:#排除不合法选择
                    continue
                track.append(nums[i])#做选择
                backtrack(nums, track, res)#递归
                track.pop()  # 撤销选择

        res = []  # 结果
        track = []  # 路径
        backtrack(nums, track, res)
        return res

JavaScript

var permute = function(nums) {
    const res = []
    const track = []
    const dfs=(nums,track,res)=>{
        //递归出口:找到符合条件的一条路径
        if(track.length == nums.length){
            res.push(track.slice()) //往结果数组增加一条路径
            return
        }
        for(const num of nums){
            //如果当前路径已经走过,就不走
            if(track.includes(num)) continue
            track.push(num)//加入路径
            dfs(nums,track,res)//递归
            track.pop()//撤回路径,以便下一次选择
        }
    }

    dfs(nums,track,res)
    return res
};

优化-使用备忘录

var permute = function(nums) {
    const res = []
    const track = []
    const used ={}//利用字典记录路径是否走过

    const dfs=(nums,track,res)=>{
        //递归出口:找到符合条件的一条路径
        if(track.length == nums.length){
            res.push(track.slice()) //往结果数组增加一条路径
            return
        }
        for(const num of nums){
            //如果当前路径已经走过,就不走
            if(used[num]) continue
            track.push(num)//加入路径
            used[num] = true//记录路径走过
            dfs(nums,track,res)//递归
            track.pop()//撤回路径,以便下一次选择
            used[num]=false//撤销记录
        }
    }

    dfs(nums,track,res)
    return res
};

47.题目

  • 给定一个可包含重复数字的序列 nums ,按任意顺序 返回所有不重复的全排列。

示例 1:

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

示例 2:

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

题解:回溯

  • 先对数组进行排序,把相同的元素放一起好进行剪枝;used记录每个元素在当前路径中是否已经被使用过。确保每个元素在当前路径中只被选择一次,并且得到不重复的全排列结果。
class Solution:
    def permuteUnique(self, nums: List[int]) -> List[List[int]]:
        def backtrack(nums: List[int], track: List[int], res: List[List[int]],used:List[bool]):
            if len(track) == len(nums):#触发结束条件:nums中的元素全都在track中出现
                res.append(track[:])  # 将路径加入结果
                return
            for i in range(len(nums)):
                if used[i]:
                    continue
                #第一个i=0不会重复,由于排好序了,当前与前一个重复就并且前面那个已经记录好了,就进行逃过(即剪枝)
                if i>0 and nums[i] == nums[i-1] and not used[i-1]:#排除不合法选择
                    continue
                track.append(nums[i])#做选择
                used[i]=True#used[i] 设置为 True,表示该元素已经被使用
                backtrack(nums, track, res,used)#递归
                track.pop()  # 撤销选择
                used[i]=False
        #对 nums 进行排序,以便相同的元素相邻,为后面的去重操作奠定基础。
        nums.sort()
        res = []  # 结果
        track = []  # 路径
        used=[False]*len(nums)#used记录每个元素在当前路径中是否已经被使用过。确保每个元素在当前路径中只被选择一次,并且得到不重复的全排列结果。
        backtrack(nums, track, res,used)
        return res
posted @   Frommoon  阅读(14)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· winform 绘制太阳,地球,月球 运作规律
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
点击右上角即可分享
微信分享提示