LeetCode: 46. Permutations

Medium

Given a collection of distinct integers, return all possible permutations.

Example:

Input: [1,2,3]
Output:
[
  [1,2,3],
  [1,3,2],
  [2,1,3],
  [2,3,1],
  [3,1,2],
  [3,2,1]
]

解法:(回溯)

本题要求生成全排列,那么看看我们能找到什么规律。以[1,2,3]为例,全排列是

[1,2,3]
[1,3,2]
[2,1,3]
[2,3,1]
[3,1,2]
​​​​​​​[3,2,1]

如果从纵向看这些全排列,直觉上能发现第一列就是分别以原数组的第0位,第1位和第2位的数字作为每个全排列的开头,然后其余的数字放到后面并通过一次交换位置形成两组新的全排列。


那么如果数组中的数字多余3个呢?比如[1,2,3,4],规律还成立吗?

[1,2,3,4]
[1,2,4,3]
[1,3,2,4]
[1,3,4,2]
[1,4,2,3]
[1,4,3,2]
[2,1,3,4]
[2,1,4,3]
[2,3,1,4]
[2,3,4,1]
[3,1,2,4]
​​​​​​​[3,1,4,2]
​​​​​​​[3,4,1,2]
​​​​​​​​​​​​​​[3,4,2,1]
​​​​​​​​​​​​​​​​​​​​​[4,1,2,3]
​​​​​​​​​​​​​​​​​​​​​​​​​​​​[4,1,3,2]
​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​[4,2,1,3]
​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​[4,2,3,1]
​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​[4,3,1,2]
​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​[4,3,2,1]

可以看出来,第一列依然符合之前的规律,如果把第一列遮挡住,第2,3,4列其实就是在重复刚才[1, 2, 3]的规律。只不过这次数组里的数字是[2,3,4]罢了。

有了这个规律,我们就可以写出如下算法:

public static List<List<Integer>> permute(int[] nums) {
        List<Integer> list = new ArrayList<>();
        for(int i : nums) {
            list.add(i) ;
        }
        List<List<Integer>> res = new ArrayList<>();
        backTrack(nums.length, list, res, 0);
        
        return res;
    }

    
    private static void backTrack(int max_len, List<Integer> currList,  List<List<Integer>> res, int first) {
        if(first == max_len) {
            res.add(new ArrayList<>(currList)) ;
//            for(int num : currList){
//                System.out.print(num+" ");
//            }
//            System.out.println() ;
        }
        
        for(int i=first; i<max_len; i++) {
            Collections.swap(currList, first, i);
            backTrack(max_len, currList, res, first + 1) ;
            Collections.swap(currList, first, i);
        }
    }

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

yexianyi

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

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

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

打赏作者

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

抵扣说明:

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

余额充值