【发布时间】:2018-03-03 10:02:47
【问题描述】:
给定一个整数数组,是否可以将整数分成两组,使得一组的和是 10 的倍数,而另一组的和是奇数。每个 int 必须在一个组中。编写一个递归帮助器方法,它接受你喜欢的任何参数,并从 splitOdd10() 对你的递归帮助器进行初始调用。 (不需要循环。)
这是我的解决方案代码:(是的,我使用了两种辅助方法而不是一种) 这就是我试图解决问题的方式:(如果我做错了什么,请纠正我)。
nums 中的每个数字只能出现在其中一个组中,group1 或 group2。对于这种情况,元素进入 group1 - group1 += nums[start] 并以这种方式对 nums 中的每个元素进行递归,直到最后一项被传递 - 其中索引 start 超出了 nums - start >= nums.length 的范围.在这样做之后,我们最终在这种可能性“树”中的所有分支的末尾有两个组group1 和group2。然后检查是否存在两组,其中一组的总和是 10 的倍数,而另一组的总和是奇数 - compare(group1, group2)。
我认为这就是我的代码行为不端的地方 - 在对 compare(group1,group2) 的调用中。我尝试如果group1 是 10 的倍数并且 group 2 是奇数 - if( a%10 == 0 && b%2 == 1) return true; 然后,因为我们不知道发生了相反的情况并且 group1 原来是奇数并且 group2 是 10 的倍数,我也检查了if( a%2 == 1 && b%10 == 0 ) return true; 这不适用于所有情况。Here is a screenshot of code output in codingbat.com。但是注释掉compare(group1,group2 的第一个条件可以神奇地修复它。Here is a working code
public boolean splitOdd10(int[] nums) {
return( splitter(nums,0,0,0) );
}
public boolean splitter(int [] nums,int start, int group1, int group2){
if (start >= nums.length ) return compare(group1,group2);
if( splitter(nums,start + 1, group1 += nums[start], group2 ) ) return true; // first condition add element in group1 and recurse on
if( splitter(nums,start + 1, group1, group2 += nums[start] ) ) return true;// second condition add element to group2
return false;
}
public boolean compare( int a, int b){
if( a%10 == 0 && b%2 == 1) return true;// <--- if I remove this line the code works
if( a%2 == 1 && b%10 == 0 ) return true;
return false;
}
我的问题是:我们如何“知道”检查哪个组是奇数以及检查哪个组是 10 的倍数?我检查了两个组的两种情况,但显然这是错误的,并且没有为某些数组返回正确的结果。例如,它为数组 [10,0,5,5] 返回“true”,而不是“false”。请帮助我理解为什么检查这两种情况都不正确。
【问题讨论】:
-
+=是一个修改操作。这意味着您计算的group1 += nums[start]在第一个if修改group1中传递给splitter,因此您在第二次调用splitter时看到修改后的值。这是故意的吗? -
您需要在这里做的第一件事是使用调试器逐行执行您的代码。检查每个方面、每个局部变量、每个返回值等是否符合您的预期。
-
我觉得不仅仅是编码问题...
-
不一定可以根据这些规则将整数集合分成两组。以下是示例:{1}、{1,2}、...、{10, 12}、{12, 13}...
-
抱歉,@T.J.Crowder,是的,这是故意的。我的思路是这样的:对于数组
nums的每个“元素”,有两种可能性:要么进入group1(因此是group1 += nums[start]或另一个。