给定一个不含重复数字的数组 nums ,返回其 所有可能的全排列 。你可以 按任意顺序 返回答案。
leetcode题目:leetcode.cn/problems/pe…
Java + 递归 方法实现
采用递归方法实现:
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数组。
其实现逻辑如下:
- 从右至左找第一个左邻小于右邻的数,记下位置i和值list[a]。
- 从右边往左找第一个右边大于list[a]的第一个值,记下位置j和值list[b]。
- 交换list[a]和list[b]的值。
- 将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); /* 递归调用 */
}
}
}