Java算法问题
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java算法问题相关的知识,希望对你有一定的参考价值。
问题陈述::在Java中,给定一个整数数组,是否可以选择一组整数的组,使得该组与给定目标的总和,具有以下附加约束:如果数组中有数字,则相邻且相同的值,它们必须全部被选中,或者都不被选择。例如,对于数组1,2,2,2,5,2,必须选择或不选择中间的所有三个2,所有都作为一个组。 (一个循环可用于查找相同值的范围)。
groupSumClump(0, 2, 4, 8, 10) → true
groupSumClump(0, 1, 2, 4, 8, 1, 14) → true
groupSumClump(0, 2, 4, 4, 8, 14) → false --> Failing Test Case
groupSumClump(0, 8, 2, 2, 1, 9) → true --> Failing Test Case
groupSumClump(0, 8, 2, 2, 1, 11) → false --> NegativeArraySizeException
我做了一些初步分析,部分代码如下。
public boolean groupSumClump(int start, int[] nums, int target)
start = 0;
boolean flag = false;
// get the highest int from the list of array we have
int highestInteger = getTheBiggest(nums);
if (highestInteger > target)
flag = false;
else
int variable = 0;
for (int i = 0; i < nums.length; i++)
variable += nums[i];
if (variable == target)
flag = true;
else
if (variable < target)
flag = false;
else
// here goes ur grouping logic here
flag = summate(highestInteger, target, nums);
return flag;
private boolean summate(int highestInteger, int target, int[] nums)
boolean val = false;
if (highestInteger == target)
val = true;
else
int[] temp = new int[nums.length - 1];
int var = 0;
if ((target - highestInteger) > 0)
for (int j = 0; j < nums.length-1; j++)
if (nums[j] != highestInteger)
temp[var] = nums[j];
if (temp[var] == (target - highestInteger))
val = true;
return val;
var++;
val = summate(getTheBiggest(temp), target - highestInteger,
temp);
return val;
private int getTheBiggest(int[] nums)
int biggestInteger = 0;
for (int i = 0; i < nums.length; i++)
if (biggestInteger < nums[i])
biggestInteger = nums[i];
return biggestInteger;
请注意:我不知道如何处理下面的问题陈述的逻辑:问题有一个Additional Constraint
,如果数组中有相邻的数字和相同的值,它们必须全部被选中,或者没有他们选择了。例如,对于数组1,2,2,2,5,2,必须选择或不选择中间的所有三个2,所有都作为一个组。 (一个循环可用于查找相同值的范围)。
我应该如何在上述问题中处理这部分逻辑。我一直在努力做到这一点,不知道。提供的建议将不胜感激。 Culd你让我知道代码有什么问题/如何处理这个问题中的附加约束, - :((
附加约束表示你选择作为一个组而不选择作为一个组。所以我不知道如何继续。如果你能帮助我。我将不胜感激。
编辑用户 - > MISSINGNO:我已将下面的代码构造添加到上面的主代码中,它打印出错误的值。我错了。
groupSumClump(0,2,4,4,8,14)→false再次失败2 8 4标志是 - > true这是错误的。
for(int number=0;number<nums.length-1;number++)
if(nums[number]==nums[number+1])
nums[number]=nums[number]+nums[number+1];
我会将数组转换为一个更简单的数组,可以使用前面的方法解决,通过聚集相邻的值:
1, 2, 2, 2, 5, 2 --> 1, 6, 5, 2
您可能希望保留一些额外的簿记信息,以便能够从解决方案中找到原始解决方案。
此问题类似于查找数组中的整数组,该数组总计给定目标。
这个问题的提示是:
基本情况是start> = nums.length。在这种情况下,如果target == 0则返回true。否则,请考虑nums [start]处的元素。关键的想法是只有两种可能性 - 选择nums [start]或不选择nums [start]。如果选择了nums [start],则进行一次递归调用以查看解决方案是否可行(在该调用中从目标中减去nums [start])。如果未选择nums [start],则进行另一次递归调用以查看是否可以使用解决方案。如果两个递归调用中的任何一个返回true,则返回true。
您可以使用相同的提示,但在其中有一个循环,以查找数组中重复数字的总和。如果选择了总和,则调用以查看是否可以求解,如果未选择求和则进行另一次调用。如果两个递归调用中的任何一个返回true,则返回true。
我认为这会有所帮助。
public boolean groupSumClump(int start, int[] nums, int target)
if(start >= nums.length) return target == 0;
int count = 1;
while(start+count < nums.length && nums[start] == nums[start+count])
count++;
if(groupSumClump(start+count, nums, target-count*nums[start])) return true;
if(groupSumClump(start+count, nums, target)) return true;
return false;
一旦你完成了missingno
的预处理步骤(线性时间),你所拥有的基本上就是subset sum problem。这是一个相当困难的问题,但存在近似算法 - 根据序列的长度,结果可能变得切实可行。
问题陈述含糊不清,不清楚:
使用这个附加约束:如果数组中有相邻的数字和相同的值,则必须全部选择它们,或者不选择它们。例如,对于数组1,2,2,2,5,2,必须选择或不选择中间的所有三个2,所有都作为一个组
如果“条纹”没有成功,如何选择单个数字?同样的例子:1,2,2,2,5,2
在一个递归调用中,我们选择2 2 2的条纹(来自上面的答案)* if(groupSumClump(start + count,nums,target-count * nums [start]))返回true *
在下一个rec。为什么我们不能在nums [start]中减去第一个单位数:if(groupSumClump(start + count,nums,target))return true;
我可以这样做:
if(groupSumClump(start + 1,nums,target - nums [start]))返回true;
这意味着我们永远不能选择单一数字?
方法groupSumClump
的公共方法参数列表不应公开start
参数,特别是如果您有一个覆盖它的内部变量。
看看这个实现。 solve
方法的时间复杂度是O(2^N)
,因为在最坏的情况下,你有义务检查所有可能的nums
子集。除非有人证明NP = P
。
我希望它有所帮助。
import java.util.*;
public class SubsetSumSolver
public boolean solve(int[] nums, int target)
return solve(0, 0, target, mergeSameNumbers(nums));
private boolean solve(int start, int tempSum, int sum, ArrayList<Integer> nums)
if (start == nums.size())
return sum == tempSum;
return solve(start + 1, tempSum + nums.get(start),sum, nums) || solve(start + 1, tempSum, sum, nums);
private ArrayList<Integer> mergeSameNumbers(int[] nums)
if (nums.length == 0)
return toArrayList(nums);
LinkedList<Integer> merged = new LinkedList<>();
int tempSum = nums[0];
for (int i = 1; i < nums.length; i++)
if (nums[i - 1] == nums[i])
tempSum += nums[i];
else
merged.add(tempSum);
tempSum = nums[i];
merged.add(tempSum);
return new ArrayList(merged);
private ArrayList<Integer> toArrayList(int[] nums)
ArrayList<Integer> result = new ArrayList();
for (int index = 0; index < nums.length; index++)
result.add(nums[index]);
return result;
我用HashMap的解决方案。
public boolean groupSumClump(int start, int[] nums, int target)
Map<Integer, Integer> map = new HashMap<Integer, Integer>();
Arrays.sort(nums);
for (int i : nums)
if (!map.containsKey(i))
map.put(i, 1);
else
map.put(i, map.get(i) + 1);
return groupSumClumpHelper(start, nums, target, map);
private boolean groupSumClumpHelper(int start, int[] nums, int target, Map map)
if (start >= nums.length)
return target == 0;
if (!map.get(nums[start]).equals(1))
return groupSumClumpHelper(start + Integer.parseInt(map.get(nums[start]).toString()), nums, target - Integer.parseInt(map.get(nums[start]).toString()) * nums[start], map) ||
groupSumClumpHelper(start + Integer.parseInt(map.get(nums[start]).toString()), nums, target, map);
return groupSumClumpHelper(start + 1, nums, target - nums[start], map) || groupSumClumpHelper(start + 1, nums, target, map);
以上是关于Java算法问题的主要内容,如果未能解决你的问题,请参考以下文章