全排列【46. 全排列】

一,题目描述

力扣

46. 全排列

难度中等1767

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

通过次数509,288提交次数648,956

二,思想

总结规律:
        1,当只有一个元素时,全排列总共只有1种;
        2,当有两个元素时,比如【1,2】,全排列有【1,2】、【2,1】两种;规律是,视为在【1】中添加元素2,那么有两种方式,在1的前边和在1的后边,即下边为0和下标为1;
        3,当有三个元素时,比如【1,2,3】,全排列有6种,规律是,视为在【1,2】、【2,1】中分别添加元素3,在【1,2】中添加元素3有3种方式,即【1,2】中的下标分别为0、1、2的时候,【2,1】同理。

        所以规律就是,数组中n个元素的全排列的数量为:n*数组中n-1个元素的全排列的数量,规律是将n插入数组中n-1个元素的全排列的所有集合;
        这种根据上一个解,得出当前解的方式,类似于动态规划的解法。

三,代码


    /**
     * 总结规律:
     * 1,当只有一个元素时,全排列总共只有1种;
     * 2,当有两个元素时,比如【1,2】,全排列有【1,2】、【2,1】两种;规律是,视为在【1】中添加元素2,那么有两种方式,在1的前边和在1的后边,即下边为0和下标为1;
     * 3,当有三个元素时,比如【1,2,3】,全排列有6种,规律是,视为在【1,2】、【2,1】中分别添加元素3,在【1,2】中添加元素3有3种方式,即【1,2】中的下标分别为0、1、2的时候,【2,1】同理。
     * 所以规律就是,数组中n个元素的全排列的数量为:n*数组中n-1个元素的全排列的数量,规律是将n插入数组中n-1个元素的全排列的所有集合;
     * 这种根据上一个解,得出当前解的方式,类似于动态规划的解法。
     *
     * @param nums
     * @return
     */
    public static List<List<Integer>> permute(int[] nums) {
        List<List<Integer>> finalOutList = new ArrayList<>();
        if (nums == null || nums.length == 0) {
            return null;
        } else if (nums.length == 1) {
            List<Integer> list1 = new ArrayList<>();
            list1.add(nums[0]);
            finalOutList.add(list1);
            return finalOutList;
        } else if (nums.length == 2) {
            List<Integer> list1 = new ArrayList<>();
            List<Integer> list2 = new ArrayList<>();
            list1.add(nums[0]);
            list1.add(nums[1]);
            list2.add(nums[1]);
            list2.add(nums[0]);
            finalOutList.add(list1);
            finalOutList.add(list2);
            return finalOutList;
        } else {
            int ele1 = nums[0];
            int ele2 = nums[1];
            List<Integer> list1 = new ArrayList<>();
            list1.add(ele1);
            List<List<Integer>> outList = permuteHelp(list1, ele2);

            //遍历每个元素:
            for (int i = 2; i < nums.length; i++) {
                int currEle = nums[i]; //当前元素;
                List<List<Integer>> outListCopy = new ArrayList<>(outList);
                for (int j = 0; j < outList.size(); j++) {
                    List<Integer> list = outList.get(j);
                    List<List<Integer>> outListTemp = permuteHelp(list, currEle);
                    outListCopy.remove(0);
                    outListCopy.addAll(outListTemp);
                }
                outList = outListCopy;
            }
            return outList;
        }
    }

    public static List<List<Integer>> permuteHelp(List<Integer> list, int insertEle) {
        List<List<Integer>> outList = new ArrayList<>();
        if (list.size() == 0) {
            list.add(insertEle);
            outList.add(list);
            return outList;
        } else if (list.size() > 0) {
            for (int i = 0; i < list.size() + 1; i++) {
                List<Integer> listTemp = new ArrayList<>();
                listTemp.addAll(list);
                listTemp.add(i, insertEle);
                outList.add(listTemp);
            }
        }
        return outList;
    }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值