全排序问题解法

98 阅读2分钟

给定一个不含重复数字的数组 nums ,返回其 所有可能的全排列 。你可以 按任意顺序 返回答案。

leetcode题目:leetcode.cn/problems/pe…

Java + 递归 方法实现

image.png 采用递归方法实现:

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class AllSort {
    public static void main(String[] args) {
        Solution solution = new Solution();
        int[] a = new int[]{21, 10, 39};
        solution.permute(a);
    }
}

class Solution {
    List<List<Integer>> result = new ArrayList<>();
    public List<List<Integer>> permute(int[] nums) {
        Map<Integer, Integer> notUsed = new HashMap<>();
        for (int i = 0; i < nums.length; i++) {
            notUsed.put(i, nums[i]);
        }

        List<Integer> res = new ArrayList<>();
        recursion(notUsed, res);
        return result;
    }

    /**
     * 递归实现全排序问题
     * 遍历所有没有使用的元素,将其加入到结果中
     * 
     * @param notUsed 记录目前没有被使用的元素
     * @param res 记录迭代到目前所有的可能性
     */
    void recursion(Map<Integer, Integer> notUsed, List<Integer> res) {
        notUsed.forEach((k, v) -> {
            List<Integer> newr = new ArrayList<>();
            newr.addAll(res);
            newr.add(v);

            Map<Integer, Integer> newNotUsed = new HashMap<>();
            newNotUsed.putAll(notUsed);
            newNotUsed.remove(k);

            if (newNotUsed.size() == 0) {
                result.add(newr);
            } else {
                recursion(newNotUsed, newr);
            }
        });
    }
}

Java + 字典序实现

什么是字典序?字典排序算法是一种基于字典序的排序算法,即将元素按照字典顺序进行排序。具体来说,对于任意两个元素a和b,如果a在b之前出现,则a小于b;否则,a大于b。

用在全排序中,a 相当于 一个list数组。

其实现逻辑如下:

  1. 从右至左找第一个左邻小于右邻的数,记下位置i和值list[a]。
  2. 从右边往左找第一个右边大于list[a]的第一个值,记下位置j和值list[b]。
  3. 交换list[a]和list[b]的值。
  4. 将i以后的元素重新按从小到大的顺序排列。

代码实现逻辑如下:

import java.util.ArrayList;
import java.util.List;

public class AllSortDic {
    public static void main(String[] args) {
        SolutionDic solution = new SolutionDic();
        int[] a = new int[]{3, 7, 9,11};
        List<List<Integer>> s =  solution.permute(a);
        for (int i = 0; i < s.size(); i++) {
            System.out.println(s.get(i).toString());
        }
    }
}
class SolutionDic {
    public List<List<Integer>> permute(int[] nums) {
        List<List<Integer>> result = new ArrayList<>();

        // step1: 对nums进行排序
        quickSort(nums);
        result.add(convert(nums));

        // step2: 从右向左找第一个 左小于右 边数据的
        while (true) {
            int a = -1;
            for (int r = nums.length - 1; r > 0; r--) {
                if (nums[r - 1] < nums[r]) {
                    a = r - 1;
                    break;
                }
            }

            // step3: 从右向左找第一个 大于nums[a]的数据,并进行交换
            if (a > -1) {
                for (int r = nums.length - 1; r > a; r--) {
                    if (nums[r] > nums[a]) {
                        int t = nums[r];
                        nums[r] = nums[a];
                        nums[a] = t;
                        break;
                    }
                }

                // step4: 将a之后的数据进行排序
                quick_sort(nums, a + 1, nums.length-1);
                result.add(convert(nums));
            } else {
                break;
            }
        }

        return result;
    }

    List<Integer> convert(int[] nums) {
        List<Integer> res = new ArrayList<>();
        for (int i = 0; i < nums.length; i++) {
            res.add(nums[i]);
        }

        return res;
    }

    // 快排序接口
    void quickSort(int[] nums) {
        quick_sort(nums, 0, nums.length - 1);
    }

    void quick_sort(int a[], int l, int r) {
        if (l < r) {
            int i, j, x;

            i = l;
            j = r;
            x = a[i];
            while (i < j) {
                while (i < j && a[j] > x)
                    j--; // 从右向左找第一个小于x的数
                if (i < j) {
                    a[i++] = a[j];
                }
                while (i < j && a[i] < x)
                    i++; // 从左向右找第一个大于x的数
                if (i < j) {
                    a[j--] = a[i];
                }
            }
            a[i] = x;
            quick_sort(a, l, i - 1); /* 递归调用 */
            quick_sort(a, i + 1, r); /* 递归调用 */
        }
    }
}