原問題描述模糊(\"0,1,2,3這三個數每行一個數共15行\..."),無法直接給出代碼。本文梳理常見排列組合場景,提供標準Java實現模板,助你根據實際需求選擇。
| 場景描述 | 數學概念 | 輸出示例 (輸入 0,1,2,3) |
|---|---|---|
| 從4個數中選3個,**有序**排列 | 排列 P(4,3) = 24 | 012, 013, 021, 023, 031, 032, 102, 103... |
| 從4個數中選3個,**無序**組合 | 組合 C(4,3) = 4 | 012, 013, 023, 123 |
| 4個數**全排列** | P(4,4) = 24 | 0123, 0132, 0213, 0231... |
| 允許重複,長度3的**有序排列** | 4^3 = 64 | 000, 001, 002, 003, 010... |
| 生成15行,每行從0-3隨機取一個數 | 隨機採樣 | 0, 3, 1, 2, 0, 1, 3, 2, 3, 0, 1, 2, 3, 1, 0 |
import java.util.*;
public class Combinatorics {
// 核心遞歸:從 candidates 選擇,構建 path,滿足條件加入 result
public static void backtrack(List candidates, List path,
List> result,
boolean[] used, // 用於不重複選擇
int targetLength, boolean allowRepeat) {
if (path.size() == targetLength) {
result.add(new ArrayList<>(path));
return;
}
for (int i = 0; i < candidates.size(); i++) {
if (used[i]) continue; // 不允許重複時跳過已用
// 剪枝邏輯可在這裡添加(如去重、順序限制)
used[i] = true;
path.add(candidates.get(i));
backtrack(candidates, path, result, used, targetLength, allowRepeat);
path.remove(path.size() - 1);
used[i] = false;
// 允許重複時,不標記 used,但需控制遞歸深度防無限循環
if (allowRepeat) {
// 需額外邏輯控制,如按索引非遞減保證無序組合不重複
}
}
}
// 便捷入口
public static List> permute(int[] nums, int k) { // 排列 P(n,k)
List> res = new ArrayList<>();
backtrack(Arrays.stream(nums).boxed().toList(), new ArrayList<>(), res,
new boolean[nums.length], k, false);
return res;
}
public static List> combine(int[] nums, int k) { // 組合 C(n,k)
List> res = new ArrayList<>();
// 組合需保證索引遞增避免重複
combineHelper(nums, 0, k, new ArrayList<>(), res);
return res;
}
private static void combineHelper(int[] nums, int start, int k,
List path, List> res) {
if (path.size() == k) { res.add(new ArrayList<>(path)); return; }
for (int i = start; i < nums.length; i++) {
path.add(nums[i]);
combineHelper(nums, i + 1, k, path, res);
path.remove(path.size() - 1);
}
}
}
// 全排列 (借用第三方庫或自寫工具)
// 隨機採樣 15 行
new Random().ints(15, 0, 4).forEach(System.out::println); // 0-3隨機數
// 笛卡爾積 (允許重複排列)
List cartesian = Stream.of(new int[]{0,1,2,3}, new int[]{0,1,2,3}, new int[]{0,1,2,3})
.reduce(Stream.of(new int[0]),
(a, b) -> a.flatMap(x -> Arrays.stream(b).map(y -> concat(x, y))),
(a, b) -> a)
.collect(Collectors.toList());
算法無萬能鑰,精確定義問題模型是解題第一步。補全上述信息,任意語言皆可實現。