
✅创作者:陈书予
🎉个人主页:陈书予的个人主页
🍁陈书予的个人社区,欢迎你的加入: 陈书予的社区
🌟专栏地址: Java华为OD机试真题(2022&2023)
文章目录
- 1. 题目描述
- 2. 输入描述
- 3. 输出描述
- 4. Java算法源码
- 5. 测试
- 6.解题思路
1. 题目描述
给你一个整数M和数组N,N中的元素为连续整数,要求根据N中的元素组装成新的数组R。
组装规则:
R中元素总和加起来等于M;
R中的元素可以从N中重复选取;
R中的元素最多只能有1个不在N中,且比N中的数字都要小(不能为负数)
2. 输入描述
第一行输入是连续数组N,采用空格分隔;
第二行输入数字M;
3. 输出描述
输出的是组装办法数量,int类型。
补充:
1 <= N.length <= 30
1 <= N.length <= 1000
4. Java算法源码
/**
* 给你一个整数M和数组N
*
* N中的元素为连续整数,要求根据N中的元素组装成新的数组R
*
* 1、R中元素总和加起来等于M
* 2、R中的元素可以从N中重复选取
* 3、R中的元素最多只能有1个不在N中,且比N中的数字都要小(不能为负数)
*/
// 组装办法数量
private static int sum = 0;
private static int min = Integer.MAX_VALUE;
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
// 连续数组N,采用空格分隔
String[] N = sc.nextLine().split(" ");
// 新数组R数字之和 = 数字M
int M = sc.nextInt();
// 数组N
int[] arr = new int[N.length];
for (int i = 0; i < N.length; i++) {
arr[i] = Integer.parseInt(N[i]);
// 取数组N的最小值
min = Math.min(min, arr[i]);
}
get(0, arr, M, 0);
System.out.println(sum);
}
/**
*
* @param idx
* @param n 连续数组N,采用空格分隔
* @param M 新数组R数字之和 = 数字M
* @param rSum 新数组R数字之和
*/
public static void get(int idx, int[] n, int M, int rSum) {
if (rSum == M) {
sum++;
return;
}
if (rSum > M) {
return;
}
/**
* R中的元素最多只能有1个不在N中,且比N中的数字都要小
*
* 新数组R数字之和 - 当前新数组R数字之和 <= 取数组N的最小值
*/
if (M - rSum <= min - 1) {
sum++;
return;
}
for (int i = idx; i < n.length; i++) {
get(i, n, M, rSum + n[i]);
}
}
5. 测试

6.解题思路
- 读取输入的连续数组
N和数字M。 - 将连续数组
N转换为整数数组arr。 - 初始化变量
sum表示组装办法数量,初始值为 0。 - 初始化变量
min表示数组N中的最小值,初始值为正无穷大。 - 遍历数组
N,将每个元素转换为整数,并更新min的值为数组N的最小值。 - 调用递归函数
get(0, arr, M, 0),计算组装办法数量。 - 在递归函数
get中,如果当前新数组R的数字之和等于M,则将sum加 1。 - 如果当前新数组
R的数字之和大于M,则返回。 - 如果
M - rSum <= min - 1,表示剩余的数字和已经小于等于min - 1,则将sum加 1,并返回。 - 否则,从当前索引
idx开始遍历数组N,递归调用get函数,更新索引idx和新数组R的数字之和rSum。 - 最后,输出组装办法数量
sum。




















