Permutations 排列的实现

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

For example,
[1,2,3] have the following permutations:

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

----------------------------------------------------------------------------------------------------

在这里,将介绍2种排列方法。

第一种方法非常容易理解:基于回溯的思想。

额外设置一个isUsed数组,来标记这个index下的数有没有被使用。

每次,我们都挑选一个没有被使用的数,加到我的list中去,继续递归

当我的list满了,则将这个list加到最终的result中去。

1. 比如,一开始1, 2, 3都没有被使用,假设我们挑了2, (此时有1, 2, 3 这3种选择)

2. 在挑了2后,我们选择3 (此时有1, 3 这2种选择)

3. 最后,只有1没有被使用了,挑选1.

这只是其中的一种情况,我们继续回上去,看有没有别的可能。

用递归的时候要注意:恢复现场

比如设置了isUsed[ i ] = true ;  往list加过东西。

在递归完了后,要变回原样(isUsed[ i ] = false, list中添加的东西删掉)


运行时间:



代码:

    public List<List<Integer>> permute(int[] nums) {
        List<List<Integer>> result = new ArrayList<>();
        List<Integer> store = new ArrayList<>();
        boolean[] isUsed = new boolean[nums.length];
        doPermute(nums, isUsed, store, result);
        return result;
    }

    private void doPermute(int[] nums, boolean[] isUsed, List<Integer> store, List<List<Integer>> result) {
        if (store.size() == nums.length) {
            result.add(new ArrayList<>(store));
            return;
        }
        for (int i = 0; i < nums.length; i++) {
            if (!isUsed[i]) {
                store.add(nums[i]);
                isUsed[i] = true;
                doPermute(nums, isUsed, store, result);
                store.remove(store.size() - 1);
                isUsed[i] = false;

            }
        }
    }



第二种方法:

第二种方法的思想是这样的:

假设我们的输入时{1,2, 3} 

1. 我们先将1 加入,得到 { 1 } 

2. 接着,2可以加到1的前面或者后面, 得到 { 1, 2 }, { 2, 1 }

3. 接着是3了, 3 可以选择{ 1, 2 } 选择加入index = 0, 1, 2中的位置。

   对于{1, 2 } 可以得到 {3, 1, 2 }, {1, 3, 2 } ,{ 2, 1, 3 }

   对于{2, 1}  可以得到{3, 2, 1 },  {2, 3, 1},  {2, 1,3}


运行时间:(跟第一种方法一样)



代码:

    public List<List<Integer>> permute2(int[] nums) {
        List<List<Integer>> result = new ArrayList<>();
        if (nums.length == 0) {
            return result;
        }
        List<Integer> curList = new ArrayList<>();
        curList.add(nums[0]);
        result.add(curList);
        int index = 1;
        while (index < nums.length) {
            List<List<Integer>> newResult = new ArrayList<>();
            for (List<Integer> list : result) {
                for (int j = 0; j <= index; j++) {
                    List<Integer> newList = new ArrayList<>(list);
                    newList.add(j,nums[index]);
                    newResult.add(newList);
                }
            }
            result = newResult;
            index++;
        }
        return result;
    }


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值