全排列

69 篇文章 1 订阅
63 篇文章 0 订阅

给定一个没有重复数字的序列,返回其所有可能的全排列。

示例:

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

(1)
方法:字典法
思路:
(1)拿到全部排序,并且按照字典顺序;
(2)现将数组排序,然后判断是否右下一个排列,参考下一个排列
(3)循环拿到所有的排列组合,直到没有下一个排列,也就是排列已经是当前数组元素按照字典顺序倒序的组合;

class Solution {
    public List<List<Integer>> permute(int[] nums) {
        //字典法
       Arrays.sort(nums);//先排序
        List<List<Integer>> res = new ArrayList<>();
        do {
            List<Integer> temp = new ArrayList<>();
            for (Integer i : nums)
                temp.add(i);
            res.add(temp);
        } while (nextPermute(nums));
        return res;
        /**int end = nums.length - 1;
        List<List<Integer>> res = new ArrayList<>();
        permute(nums, res, 0, end);
        return res;**/
    }
        
    //判断是否有下一个全排列,有则进行下一个排列并且拿到true,无则false
    private boolean nextPermute(int[] nums) {
        int end = nums.length - 2;
        while (end >= 0 && nums[end + 1] <= nums[end])
            end --;
        if (end >= 0) {
            int temp = nums.length - 1;
            while (end >= 0 && nums[end] > nums[temp])
                temp --;
            swap(nums, end, temp);
            reverse(nums, end + 1);
        } else {
            return false;
        }
            return true;
        }
    
    //换位
    private void swap(int[] nums, int i, int j) {
        int temp = nums[i];
        nums[i] = nums[j];
        nums[j] = temp;
    }
    //反转
    private void reverse(int[] nums, int start) {
        int end = nums.length - 1;
        while (start < end) {
            swap(nums, start, end);
            start ++;
            end --;
        }
    }

(2)
方法:递归法
思路:
1,元素和它例如数组[1,3,4,2];
2,首先保持第一个元素不变,就是[3,4,2]的排列,然后保持3不变就是[4,2]的排列,在保持4不变,就只剩一个元素,就只有一种元素了,所以排列就是[1,3,4,2],往回一步,4要变那就只能4和2换位就变成了[1,3,2,4];再往回走,那就变3,则3和4,2相互换位,然后得到[1,4,3,2], [1,4,23],[1,2,4,3][1,2,3,4];
3,然后再要改变第一个元素,则将其与后面的元素换位,经过递归实现上述算法;

class Solution {
    public List<List<Integer>> permute(int[] nums) {
        int end = nums.length - 1;
        List<List<Integer>> res = new ArrayList<>();
        permute(nums, res, 0, end);
        return res;
    }
     //换位
    private void swap(int[] nums, int i, int j) {
        int temp = nums[i];
        nums[i] = nums[j];
        nums[j] = temp;
    }
    public void permute(int[] nums, List<List<Integer>> res, int begin, int end) {
        //递归法,两两换位
        //递归结束条件,两两换位后,begin = end;
        if (begin == end) {// 完成一次全排列
            List<Integer> temp = new ArrayList<>();
            for (Integer i : nums)
                temp.add(i);
            res.add(temp);
            return;
        } else {
            for (int i = begin; i <= end; i ++) {//换位
                swap(nums, begin, i);//锁定位
                permute(nums, res, begin + 1, end);//后续位
                swap(nums, begin, i);
            }
        }
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值