我在Java中有一个递归面试问题,需要你的帮助.
编写一个** Java函数**,使得::给定一个整数数组,是否可以将整数分成两组,这样两组的总和是相同的,具有这些约束:所有的值都是5的倍数必须在一个组中,并且所有3的倍数(而不是5的倍数)必须在另一个组中. (不需要循环.)
split53({1,1})→true
split53({1,1,1})→false
split53({2,4,2})→true
PS:这是hewlett packard的采访问题
解决方法:
这个问题很容易简化为:给定一组整数和整数目标,是否有可能找到总和等于目标的数字子集?
如果过渡需要澄清,请告诉我.
它可以用O(number.size * target)时间的DP来解决.这个想法如下
>当numbers.size为0时,唯一可达的总和为0.
>假设我们有数字== {1,3},在这种情况下,总和{0,1,3,4}可用.如果我们在数字4中添加另一个元素怎么办?现在,仍然可以达到所有旧的和一些新的:{0 4,1 4 3,4 4,4}.因此,对于数字== {1,3,4},可用的总和是{0,1,3,4,5,7,8}.
>以这种方式,按编号添加数字,您可以构建可达总和的列表.
一个工作示例(它不处理负数,但你可以很容易地解决它)
boolean splittable(int[] numbers, int target) {
boolean[] reached = new boolean[target + 1];
reached[0] = true;
for (int number : numbers) {
for (int sum = target - 1; sum >= 0; --sum) {
if (reached[sum] && sum + number <= target) {
reached[sum + number] = true;
}
}
}
return reached[target];
}
运行
System.out.println(splittable(new int[]{3, 1, 4}, 7)); // => true
System.out.println(splittable(new int[]{3, 1, 4}, 6)); // => false
编辑
我刚刚注意到要求的“递归”部分.好吧,如果这是硬性要求,DP可以用memoization重写为递归.这将保留运行时复杂性.
编辑2
在团体.在继续算法之前,必须将可被3或5整除的元素分配给各个组.假设所有元素的总和是s,可被3整除的元素之和是s3,可被5整除但不是3的元素之和是s5.在这种情况下,在您分配了这些“特殊”元素之后,您必须将其余部分拆分为一个组中的总和为s / 2 – s3,而另一个组中的总和为s / 2 – s5.
标签:java,algorithm,recursion
来源: https://codeday.me/bug/20190526/1157377.html