题目
给定一个整数数组nums、一个数字k,一个整数目标值target,请问nums中是否存在k个元素使得其相加结果为target,请输出所有符合条件且不重复的k元组的个数
数据范围2<= nums.length <= 200
-10^9 < nums[i] < 10^9
-10^9 < target < 10^9
2<=k<=100
输入描述第一行是nums取值:2 7 11 15
第二行是k的取值:2
第三行是target取值: 9
输出描述输出第一行是符合要求的元组个数: 1
补充说明:
[2,7]满足,输出个数是1
示例1:
输入-1 0 1 2 -1 -4
3
0
输出2
说明[-1,0,1],[-1,-1,2]满足条件
思路
组合题,直接用套路:【JAVA-排列组合】一个套路速解排列组合题
题目不要求具体组合,所以path可以省略
注意剪枝条件:
同层相同剪枝 -- 排除重复数据
将nums按照从小到大排序,如果当前值大于0,后面一定大于0,如果此时累加和已经大于等于初始目标(两者差值<=0),那么后续加一个更大的数,肯定不满足,直接break
题解
java
package hwod;
import java.util.Arrays;
import java.util.Scanner;
public class KNumsSum {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int[] nums = Arrays.stream(sc.nextLine().split(" ")).mapToInt(Integer::parseInt).toArray();
int k = Integer.parseInt(sc.nextLine());
int target = Integer.parseInt(sc.nextLine());
System.out.println(kNumSum(nums, k, target));
}
private static int res;
private static int kNumSum(int[] nums, int k, int target) {
Arrays.sort(nums);
int[] used = new int[nums.length];
dfs(nums, 0, used, k, target);
return res;
}
private static void dfs(int[] nums, int start, int[] used, int k, int target) {
if (k == 0) {
if (target == 0) res++;
return;
}
for (int i = start; i < nums.length; i++) {
if (nums[i] > 0 && target <= 0) break; //当前值都大于0,后面一定大于0,如果此时累加和已经大于等于初始目标,那么后续加一个更大的数,肯定不满足,直接break
if (i > 0 && nums[i] == nums[i - 1] && used[i - 1] == 0) continue;//同层相同剪枝
used[i] = 1;
dfs(nums, i + 1, used, k - 1, target - nums[i]);
used[i] = 0;
}
}
}
推荐
如果你对本系列的其他题目感兴趣,可以参考华为OD机试真题及题解(JAVA),查看当前专栏更新的所有题目。