需求:對陣列 {1,2,3,4} 產生所有排列 (24 種),每種排列賦值給 a1,a2,a3,a4 並執行業務邏輯。本文提供四層巢狀迴圈與遞迴回溯兩種標準實作。
int[] arr = {1, 2, 3, 4};
int count = 0;
for (int i1 = 0; i1 < 4; i1++) {
for (int i2 = 0; i2 < 4; i2++) {
if (i2 == i1) continue;
for (int i3 = 0; i3 < 4; i3++) {
if (i3 == i1 || i3 == i2) continue;
for (int i4 = 0; i4 < 4; i4++) {
if (i4 == i1 || i4 == i2 || i4 == i3) continue;
int a1 = arr[i1], a2 = arr[i2], a3 = arr[i3], a4 = arr[i4];
count++;
Console.WriteLine($"{count}: {a1} {a2} {a3} {a4}");
// 在此處呼叫業務邏輯 Process(a1, a2, a3, a4);
}
}
}
}
Console.WriteLine($"總共 {count} 種排列"); // 24
void Permute(int[] arr, int[] output, bool[] used, int depth, Action callback) {
if (depth == arr.Length) {
callback(output);
return;
}
for (int i = 0; i < arr.Length; i++) {
if (!used[i]) {
used[i] = true;
output[depth] = arr[i];
Permute(arr, output, used, depth + 1, callback);
used[i] = false;
}
}
}
// 使用
int[] arr = {1, 2, 3, 4};
int[] output = new int[4];
bool[] used = new bool[4];
int count = 0;
Permute(arr, output, used, 0, perm => {
count++;
int a1 = perm[0], a2 = perm[1], a3 = perm[2], a4 = perm[3];
Console.WriteLine($"{count}: {a1} {a2} {a3} {a4}");
// Process(a1, a2, a3, a4);
});
var perms = arr
.SelectMany(a1 => arr.Where(a2 => a2 != a1)
.SelectMany(a2 => arr.Where(a3 => a3 != a1 && a3 != a2)
.SelectMany(a3 => arr.Where(a4 => a4 != a1 && a4 != a2 && a4 != a3)
.Select(a4 => new[] { a1, a2, a3, a4 }))));
foreach (var p in perms) {
Console.WriteLine(string.Join(" ", p));
}
| 方法 | 時間複雜度 | 空間複雜度 | 適用場景 |
|---|---|---|---|
| 巢狀迴圈 | O(N!) | O(1) | N≤8 固定長度、極致效能 |
| 遞迴回溯 | O(N!) | O(N) | 通用 N、程式碼簡潔、易維護 |
| LINQ | O(N!) | O(N!) | 原型驗證、資料量小 |
若需**字典序**產生排列,可實作 NextPermutation 迭代器模式,空間 O(1)、無遞迴。
選擇遞迴回溯作為通用解法,四層迴圈作為固定 4 元素的高效能選擇,即可滿足全排列業務需求。