Java 给定目标的5倍总和
可能重复:Java 给定目标的5倍总和,java,algorithm,Java,Algorithm,可能重复: 大家好 在没有正确方向的情况下,我正在努力解决下面的问题 编写一个java函数,以便在给定一个整数数组的情况下,可以选择一组整数,从而使该组与给定的目标求和具有以下附加约束:数组中所有5的倍数都必须包含在该组中。如果紧跟在5的倍数之后的值为1,则不得选择该值 groupSum5(0,{2,5,10,4},19)→ 真的 groupSum5(0,{2,5,10,4},17)→ 真的 groupSum5(0,{2,5,10,4},12)→ 假的 groupSum5(0,{3,5,1}
大家好 在没有正确方向的情况下,我正在努力解决下面的问题 编写一个java函数,以便在给定一个整数数组的情况下,可以选择一组整数,从而使该组与给定的目标求和具有以下附加约束:数组中所有5的倍数都必须包含在该组中。如果紧跟在5的倍数之后的值为1,则不得选择该值
- groupSum5(0,{2,5,10,4},19)→ 真的
- groupSum5(0,{2,5,10,4},17)→ 真的
- groupSum5(0,{2,5,10,4},12)→ 假的
- groupSum5(0,{3,5,1},5)→ 真的
- groupSum5(0,{3,5,1},4)→ 假的
public boolean groupSum5(int start, int[] nums, int target) {
start = 0;
boolean flag = false;
for(int i=0;i<nums.length;i++){
if(nums[i]%5==0){
start+=nums[i];
}else if((start != target) && (start%5==0)){
start+=nums[i];
}else if(start == target){
flag = true;
return flag;
}else if((nums[i]%5==0) && (nums[i+1]==1)){
continue;
}
}
return flag;
}
public boolean groupSum5(int start,int[]nums,int target){
开始=0;
布尔标志=假;
对于(int i=0;i这里有一个解决方案,但请参见后面的讨论:
package so5987154;
import java.util.Collection;
import java.util.List;
import java.util.Set;
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
public class Summation {
/**
* Sum of start and every element of the collection.
*
* @param start
* starting value for the sum
* @param list
* Collection to sum.
* @return the sum.
*/
private int sum(final Integer start, final Collection<Integer> list) {
int sum = start;
for (final int i : list) {
sum += i;
}
return sum;
}
/**
* Given an array of ints, is it possible to choose a group of some of the ints, such that the group sums to the given target
* with these additional constraints: all multiples of 5 in the array must be included in the group. If the value immediately
* following a multiple of 5 is 1, it must not be chosen.
*
* @param start
* not used
* @param nums
* array of int (input)
* @param target
* target value for the summation
* @return true if we found a group that meet the criteria.
*/
public boolean groupSum5(final int start, final int[] nums, final int target) {
// list of values that need to be included (multiple of 5)
final List<Integer> fixed = Lists.newArrayList();
// list of value that can be included (anything but 1 preceded by a multiple of 5)
final List<Integer> candidates = Lists.newArrayList();
// fills candidates and fixed
for (int i = 0; i < nums.length; i++) {
final int cand = nums[i];
if (cand == 1 && i > 0) {
final int prev = nums[i - 1];
if (prev % 5 != 0) {
candidates.add(cand);
}
} else if (cand % 5 == 0) {
fixed.add(cand);
} else if (cand <= target) {
candidates.add(cand);
}
}
// compute the sum of fixed
final int sumFixed = sum(0, fixed);
// if the sum of fixed is equals to target we don't need to do anything because
// we already know we need to return true.
if (sumFixed == target) {
return true; // NOPMD
}
// if the sum of fixed is greater than target we don't need to do anything because
// we already know we need to return false (all multiple of 5 must be included)
// If candidates is empty there's no way we can achieve the desired goal.
if (sumFixed <= target && !candidates.isEmpty()) {
// generates all subsets of candidates:
// { 1, 2 } => {}, {1}, {2}, {1, 2}
final Set<Set<Integer>> powerSet = Sets.powerSet(Sets.newHashSet(candidates));
// for each found subset, computes the sum of the subset and add it to the sum of
// multiples of 5 then compare it to target. If equals => return true.
for (final Set<Integer> set : powerSet) {
if (sumFixed + sum(0, set) == target) {
return true; // NOPMD
}
}
}
return false;
}
}
但是,您的签名参数start
建议使用递归。在第一步中,您可以从int数组中删除:
- 所有5的倍数,并将其相加为开始
- 所有1前面都有5的倍数
然后使用start和int的新数组调用方法
在方法中,您需要:
- 测试start是否等于target=>返回true
- 测试启动是否超过目标=>返回false
- 测试数组是否为空=>返回false
- 使用start+x调用该方法,其中x是数组的元素,并且使用x removed=>return或返回所有结果的数组
示例:{2,5,10,4},target=19
5:5+10=15的倍数之和,1前面有5=>新数组{2,4}
第一次调用:方法(15,{2,4},19)
- 开始==目标=>否
- 开始>目标=>否
- 数组空=>否
- r1=方法(15+2,{4},19)和r2=方法(15+4,{2},19)
第二次调用(r1):方法(15+2,{4},19)
- 开始==目标=>否
- 开始>目标=>否
- 数组空=>否
- r11=方法(15+2+4,{},19)
第三次调用(r11):方法(15+2+4,{},19)
- 开始==目标=>否
- 开始>目标=>是=>false
第二次调用(r2):方法(15+4,{2},19)
- 开始==目标=>是=>true
我们回到第一个调用中,返回的是r1=r11=false
和r2=true
=>返回false或true=true
,结束
您可以看到设置。powerSet
相当于递归调用r(k)请发布一个特定的问题,而不是一般的“帮助我”。请不要编辑其他人的帖子来向他们发送消息。:)请注意,你不需要对所有评论都加50分,只需要那些你没有直接参与的评论:此外,虽然我们喜欢帮助人们解决家庭作业问题,但我们避免给出家庭作业答案——这是一个需要你解决和解决的问题。你已经发布了一个开始,这很好:)但是如果你仔细阅读@Dante的帖子,我想你会发现这是一个很好的起点。@UBM的建议很好,但如果对你来说是一个新的术语,那就不用担心了。你明年会到的。:)谢谢RC u刚刚让我开心。。如果我有澄清,我会回到ui不想使用以下两个导入。任何解决方法import com.google、 common.collect.list;
导入com.google.common.collect.set;
使用现有java集合框架的任何解决方案否,您需要按照我所做的解释编写代码,在“家庭作业”中有“工作”;)我已经对列表及其工作方式进行了更改,但希望您能为import com.google.common.collect.Sets;
提供一个替代方案,我们将不胜感激。
package so5987154.tests;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import org.junit.Test;
import so5987154.Summation;
@SuppressWarnings("PMD")
public class SummationTest {
private final Summation s = new Summation();
@Test
public void testGroupSum5() {
assertTrue(s.groupSum5(0, new int[] { 2, 5, 10, 4 }, 19));
assertTrue(s.groupSum5(0, new int[] { 2, 5, 10, 4 }, 17));
assertFalse(s.groupSum5(0, new int[] { 2, 5, 10, 4 }, 12));
assertTrue(s.groupSum5(0, new int[] { 2, 5, 10, 4 }, 19));
assertTrue(s.groupSum5(0, new int[] { 3, 5, 1 }, 5));
assertFalse(s.groupSum5(0, new int[] { 3, 5, 1 }, 4));
assertTrue(s.groupSum5(0, new int[] { 3, 1 }, 4));
assertFalse(s.groupSum5(0, new int[] { 3, 1 }, 2));
assertTrue(s.groupSum5(0, new int[] { 1 }, 1));
}
}