全排列是一種非常常見的排列問題,即給定一個數組,需要將其所有元素進行全排列,即將數組中的元素進行全排列得到新的數組。
下面介紹三種常見的全排列算法的實現。
1.遞歸算法:
遞歸算法是一種非常直觀的全排列算法,其基本思想是將數組中的第一個元素與其它元素進行交換,然后對剩余的元素進行全排列,直到只剩下一個元素為止。
具體實現如下:
public class Permutations {
public static void main(String[] args) {
int[] nums = {1, 2, 3};
permute(nums);
}
public static void permute(int[] nums) {
permute(nums, 0, nums.length - 1);
}
private static void permute(int[] nums, int l, int r) {
if (l == r) {
printArray(nums);
} else {
for (int i = l; i <= r; i++) {
swap(nums, l, i);
permute(nums, l + 1, r);
swap(nums, l, i); // 還原數組
}
}
}
private static void swap(int[] nums, int i, int j) {
int temp = nums[i];
nums[i] = nums[j];
nums[j] = temp;
}
private static void printArray(int[] nums) {
for (int num : nums) {
System.out.print(num + " ");
}
System.out.println();
}
}
2.字典序算法:
字典序算法是另一種常見的全排列算法,其基本思想是通過字典序來生成全排列。首先將數組按照字典序排序,然后不斷生成下一個排列,直到所有的排列都生成完畢。
具體實現如下:
public class Permutations {
public static void main(String[] args) {
int[] nums = {1, 2, 3};
permute(nums);
}
public static void permute(int[] nums) {
Arrays.sort(nums);
printArray(nums);
while (nextPermutation(nums)) {
printArray(nums);
}
}
private static boolean nextPermutation(int[] nums) {
int i = nums.length - 2;
while (i >= 0 && nums[i] >= nums[i + 1]) {
i--;
}
if (i >= 0) {
int j = nums.length - 1;
while (nums[j] <= nums[i]) {
j--;
}
swap(nums, i, j);
}
reverse(nums, i + 1);
return i >= 0;
}
private static void swap(int[] nums, int i, int j) {
int temp = nums[i];
nums[i] = nums[j];
nums[j] = temp;
}
private static void reverse(int[] nums, int start) {
int i = start, j = nums.length - 1;
while (i < j) {
swap(nums, i, j);
i++;
j--;
}
}
private static void printArray(int[] nums) {
for (int num : nums) {
System.out.print(num + " ");
}
System.out.println();
}
}
3.回溯算法:
回溯算法是一種非常靈活的全排列算法,其基本思想是通過遞歸的方式生成全排列。具體實現如下:
public class Permutations {
public static void main(String[] args) {
int[] nums = {1, 2, 3};
permute(nums);
}
public static void permute(int[] nums) {
List<List<Integer>> result = new ArrayList<>();
backtrack(result, new ArrayList<>(), nums);
for (List<Integer> list : result) {
printList(list);
}
}
private static void backtrack(List<List<Integer>> result, List<Integer> tempList, int[] nums) {
if (tempList.size() == nums.length) {
result.add(new ArrayList<>(tempList));
} else {
for (int i = 0; i < nums.length; i++) {
if (tempList.contains(nums[i])) {
continue;
}
tempList