首页 > 其他分享 >【LeetCode】46. 全排列

【LeetCode】46. 全排列

时间:2024-01-02 10:38:50浏览次数:35  
标签:status 排列 题目 nums 46 list int 遍历 LeetCode


一、题目描述

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

二、思路分析

这道题并不难,可以当作回溯算法的练习题。另外就是我感觉回溯和深度优先搜索是差不多的思想。

首先我可以从题目中获取一个非常重要的信息:这是一个不含重复元素的数组。 如果包含重复数字就要考虑会不会出现重复的排列。

当遇到无重复元素的排列这种题目的时候,不需要多想,就是简单暴力的去遍历每一种可能,就像小时候玩的选数字填空,假如使用1,2,3三个元素,那么我们就是在三个空位置上进行选数字,转化成图就是下面所示:

【LeetCode】46. 全排列_算法

针对上面这个例子,我们可以直接三次循环走起,遍历出所有的结果就是答案。但是我们要考虑一个情况,随着数字越来越大,我们写循环的话,代码就会越套越多,越来越长,这简直快赶上套娃了。

那么是不是有更加优雅的写法呢?

这个肯定是有滴,我们从上面那个图可以看出来什么呢?这是不是一棵树,而排列的答案就是对树中每条路径的遍历,这个也就是对树的遍历,也就变成了使用回溯算法,写代码的形式也就变成了我们常说的递归。

这里有一个需要注意的点,全排列里面一个元素不能同时出现多次,那么我们就需要一个标记数组,用来记录已经使用过元素。

class Solution {
    List<List<Integer>> result = new ArrayList<>();
    LinkedList<Integer> list = new LinkedList<>();

    public List<List<Integer>> permute(int[] nums) {
        int n = nums.length;
        backTrack(nums, new int[n], n);
        return result;
    }

    public void backTrack(int nums[], int[] status, int n) {
        if (list.size() == n) {
            result.add(new ArrayList<>(list));
            return;
        }

        for (int i = 0; i < n; i++) {
            if (status[i] == 1) {
                continue;
            }
            list.add(nums[i]);
            status[i] = 1;
            backTrack(nums, status, n);
            list.removeLast();
            status[i] = 0;
        }
    }
}

三、总结

一般来说,递归和循环都是可以相互转化的,就看哪个理解和实现起来比较容易。

全排列这种题目,基本上就是暴力解法,没有投机取巧的说法。我们可以通过把题目信息分解转化成一棵树的形式,然后对树进行遍历获取最终的答案,这样更加容易理解这一类型的题目。

标签:status,排列,题目,nums,46,list,int,遍历,LeetCode
From: https://blog.51cto.com/u_15812995/9063830

相关文章

  • 【LeetCode】2055. 蜡烛之间的盘子
    一、题目描述给你一个长桌子,桌子上盘子和蜡烛排成一列。给你一个下标从0开始的字符串s,它只包含字符'*'和'|',其中'*'表示一个盘子,'|'表示一支蜡烛。同时给你一个下标从0开始的二维整数数组queries,其中queries[i]=[lefti,righti]表示子字符串s[lefti...rig......
  • 【LeetCode】23. 合并K个升序链表
    一、题目描述给你一个链表数组,每个链表都已经按升序排列。请你将所有链表合并到一个升序链表中,返回合并后的链表。示例1:输入:lists=[[1,4,5],[1,3,4],[2,6]]输出:[1,1,2,3,4,4,5,6]解释:链表数组如下:[1->4->5,1->3->4,2->6]将它们合并到一个有序链表中得到。1->1->2......
  • #yyds干货盘点# LeetCode程序员面试金典:赎金信
    给你两个字符串:ransomNote 和 magazine ,判断 ransomNote 能不能由 magazine 里面的字符构成。如果可以,返回 true ;否则返回 false 。magazine 中的每个字符只能在 ransomNote 中使用一次。 示例1:输入:ransomNote="a",magazine="b"输出:false示例2:输入:ransomNot......
  • #yyds干货盘点# LeetCode程序员面试金典:按权重随机选择
    题目给你一个下标从0开始的正整数数组w,其中w[i]代表第i个下标的权重。请你实现一个函数pickIndex,它可以随机地从范围[0,w.length-1]内(含0和w.length-1)选出并返回一个下标。选取下标i的概率为w[i]/sum(w)。例如,对于w=[1,3],挑选下标0的概率......
  • macOS Monterey 12.6.6 (21G646) 正式版发布,ISO、IPSW、PKG 下载
    macOSMonterey12.6.6(21G646)正式版发布,ISO、IPSW、PKG下载本站下载的macOS软件包,既可以拖拽到Applications(应用程序)下直接安装,也可以制作启动U盘安装,或者在虚拟机中启动安装。另外也支持在Windows和Linux中创建可引导介质。2023年5月18日(北京时间19日凌晨),App......
  • 浅谈一类状态转移依赖邻项的排列计数问题 - 连续段 dp
    UPD2023.12.31:失手把原来的博文删掉了,这篇是补档。引入在一类序列计数问题中,状态转移的过程可能与相邻的已插入元素的具体信息相关(e.g.插入一个新元素时,需要知道与其插入位置相邻的两个元素的值是多少,才可进行状态转移,如「JOIOpen2016」摩天大楼)。这类问题通常的特点是,如......
  • leetcode 2.两数相加
    leetcode第二题:两数相加以链表为载体模仿加法进位,同时遍历两个链表,逐位计算它们的和,并与当前位置的进位值相加。如果两个链表的长度不同,则可以认为长度短的链表的后面有若干个0。如果链表遍历结束后,有carry>0,还需要在答案链表的后面附加一个节点,节点的值为carry。易错点:1.......
  • 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]......
  • 2023-12-30:用go语言,给你一个下标从 0 开始的整数数组 nums ,它包含 n 个 互不相同 的正
    2023-12-30:用go语言,给你一个下标从0开始的整数数组nums,它包含n个互不相同的正整数,如果nums的一个排列满足以下条件,我们称它是一个特别的排列。对于0<=i<n-1的下标i:要么nums[i]%nums[i+1]==0,要么nums[i+1]%nums[i]==0。请你返回特别排列的总数目,由于答......
  • 2023-12-30:用go语言,给你一个下标从 0 开始的整数数组 nums ,它包含 n 个 互不相同 的正
    2023-12-30:用go语言,给你一个下标从0开始的整数数组nums,它包含n个互不相同的正整数,如果nums的一个排列满足以下条件,我们称它是一个特别的排列。对于0<=i<n-1的下标i:要么nums[i]%nums[i+1]==0,要么nums[i+1]%nums[i]==0。请你返回特别排列的总数目......