### 华为OD机考 2025B卷 数字游戏 Java 编程题 解决方案
在华为OD机考 2025B卷中,数字游戏相关的编程题目通常涉及算法设计、数据结构应用以及逻辑推理。以下是一个可能的数字游戏问题及其解决方案。
#### 问题描述
假设有一个数字游戏,玩家需要从一个整数数组中选择若干个数字,使得这些数字的和等于目标值 `target`。要求输出所有可能的组合。如果不存在这样的组合,则返回空列表。
**输入:**
- 一个整数数组 `nums`。
- 一个整数目标值 `target`。
**输出:**
- 所有可能的组合列表,每个组合是一个子数组。
**示例:**
```plaintext
输入: nums = [2, 3, 6, 7], target = 7
输出: [[7], [2, 2, 3]]
```
#### 解决方案
以下是使用回溯法(Backtracking)解决该问题的 Java 实现:
```java
import java.util.ArrayList;
import java.util.List;
public class NumberGame {
public static List<List<Integer>> combinationSum(int[] candidates, int target) {
List<List<Integer>> result = new ArrayList<>();
if (candidates == null || candidates.length == 0) return result;
// 排序以优化剪枝
java.util.Arrays.sort(candidates);
backtrack(result, new ArrayList<>(), candidates, target, 0);
return result;
}
private static void backtrack(List<List<Integer>> result, List<Integer> tempList, int[] candidates, int remain, int start) {
if (remain < 0) return; // 超过目标值,直接返回
if (remain == 0) { // 找到一个组合
result.add(new ArrayList<>(tempList));
return;
}
for (int i = start; i < candidates.length; i++) {
tempList.add(candidates[i]);
backtrack(result, tempList, candidates, remain - candidates[i], i); // 不移动起点,允许重复使用
tempList.remove(tempList.size() - 1); // 回溯
}
}
public static void main(String[] args) {
int[] nums = {2, 3, 6, 7};
int target = 7;
List<List<Integer>> result = combinationSum(nums, target);
System.out.println("结果: " + result);
}
}
```
#### 代码说明
1. **输入排序**:为了优化剪枝操作,首先对输入数组进行排序[^1]。
2. **回溯函数**:通过递归实现回溯,每次尝试将当前数字加入临时列表,并递归调用自身以寻找剩余目标值的组合。
3. **剪枝条件**:当剩余目标值小于 0 时,停止进一步递归;当剩余目标值等于 0 时,保存当前组合并返回。
4. **重复使用元素**:允许同一个数字被多次使用,因此递归调用时传入的起点索引不增加。
#### 时间复杂度与空间复杂度
- **时间复杂度**:最坏情况下为 \(O(2^n)\),其中 \(n\) 是数组长度,因为每个数字都有选或不选两种状态。
- **空间复杂度**:取决于递归深度,最坏情况下为 \(O(n)\)[^2]。
#### 测试结果
运行上述代码,对于输入 `nums = [2, 3, 6, 7]` 和 `target = 7`,输出结果为:
```plaintext
结果: [[2, 2, 3], [7]]
```