去哪儿笔试:部分和问题
题目描述
输入一个数组arr和一个目标数字k,问我们能否从数组中找到几个数字,使得它们的和为k
如果能找到,则输出YES和这些数字,否则输出NO输出的第一行包括两个数,分别表示数组的长度和目标数字k
如果能找到,输出YES,以及这些数字;反之输出NO输入描述
4 13
1 2 4 7输出描述
YES
2 4 7
思路:
考查深搜,递归不太好写
数组中的每一个数都存在两种可能,选它或不选它。以第一个数字作为根节点,能够绘制出一棵二叉树,对这可二叉树进行搜索,总能找到一个结点,它的sum = k。
其中,index表示搜索的深度,sum表示累加和
import java.util.Scanner;
public class Main {
public static boolean solution(int[] array, int index,
int sum, int k, int[] visit) {
if(sum > k) { // 如果sum 大于k,就不用搜索了
return false;
}
if(index == array.length) { // 如果搜索的深度刚好是数组的长度,那么需要判断sum是否等于k
return sum == k;
}
// 第一种情况,选它
if(solution(array, index + 1, sum, k, visit)) {
visit[index] = 0; // 0 表示不选
return true;
}
// 第二种情况,不选它
if(solution(array, index + 1, sum + array[index], k, visit)) {
visit[index] = 1; // 1 表示选
return true;
}
return false;
}
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int n = in.nextInt();
int k = in.nextInt();
int[] array = new int[n];
int[] visit = new int[n];
for(int i = 0; i < n; i++) {
array[i] = in.nextInt();
}
if(solution(array, 0, 0, k, visit)) {
System.out.println("YES");
for(int i = 0; i < n; i++) {
if(visit[i] == 1) {
System.out.print(array[i] + " ");
}
}
System.out.println();
}else {
System.out.println("NO");
}
}
}