我对此非常困惑。该代码将生成给定整数列表的所有排列。完成此操作后,它们将添加另一个约束,即给定输入可以重复,并且我们只需要唯一的排列。
我的代码有效……我对发现的东西感到惊讶。在查看了代码之后,我问我是否有必要满足特定条件,因此我否定了它以查看会发生什么。该代码在100个测试用例中仍然可以正常工作。本质上,无论此条件是true
还是false
,此代码都有效。
很自然,我认为我可以删除条件,因为这似乎不必要。长话短说。...代码现在返回空结果集。我希望比我更聪明的人能够解释这是怎么回事,因为我现在正在质疑我是否属于这个行业。
有问题的代码行是:
if(seen[i] || (i > 0 && nums[i] == nums[i - 1] && !seen[i - 1]))
特别是!seen[i - 1]
,如果您按原样运行此代码,则可以正常运行。如果您删除否定并以seen[i - 1]
的形式运行,它仍然可以工作。如果您完全删除!seen[i - 1]
,以使条件看起来像这样:
if(seen[i] || (i > 0 && nums[i] == nums[i - 1]))
,然后代码返回空结果集。我完全感到困惑。
我正在使用[1,1,2]
作为方法的输入,我的预期结果是:[[1,1,2],[1,2,1],[2,1,1]]
class PermutationGenerator {
List<List<Integer>> result = new ArrayList<>();
public List<List<Integer>> permuteUnique(int[] nums) {
if(nums == null || nums.length == 0){
return result;
}
Arrays.sort(nums);
backtrack(nums, new ArrayList<>(), new boolean[100]);
return result;
}
private void backtrack(int[] nums, List<Integer> permutation, boolean[] seen){
if(permutation.size() == nums.length){
result.add(new ArrayList<>(permutation));
return;
}
for(int i = 0; i < nums.length; i++){
if(seen[i] || (i > 0 && nums[i] == nums[i - 1] && !seen[i - 1])){
continue;
}
seen[i] = true;
permutation.add(nums[i]);
backtrack(nums, permutation, seen);
seen[i] = false;
permutation.remove(permutation.size() - 1);
}
}
}
我的问题只是这怎么可能?代码是对还是错,都可以使用,但是将其完全删除是不可行的。
答案 0 :(得分:2)
我可以确认您的代码在否定条件的最后一部分的情况下是否会产生相同的结果,并且在条件删除后它会产生不同的结果。
这似乎是一个奇迹,除非您认为对整个条件进行多次循环评估,并且很可能三种情况(有条件,有否定条件,无条件)都具有不同的处理方式并得出结果。我要说的是,在条件与否定条件下,但以不同的方式可以达到相同的结果。
在这种情况下。如果在循环中引入一些printf-debugging,您将看到以完全不同的方式达到结果。带有否定的现有条件可使完整条件在其他迭代中变为非否定条件。完全有机会(无需进一步研究算法)最终都导致相同的结果。
这是数字i
的执行轨迹,完整条件的结果以及在该位置的nums
,seen
和result
的中间值:
无条件:
0 F [1, 1, 2] [0, 0, 0] []
0 T [1, 1, 2] [True, 0, 0] []
1 T [1, 1, 2] [True, 0, 0] []
2 F [1, 1, 2] [True, 0, 0] []
0 T [1, 1, 2] [True, 0, True] []
1 T [1, 1, 2] [True, 0, True] []
2 T [1, 1, 2] [True, 0, True] []
1 T [1, 1, 2] [False, 0, False] []
2 F [1, 1, 2] [False, 0, False] []
0 F [1, 1, 2] [False, 0, True] []
0 T [1, 1, 2] [True, 0, True] []
1 T [1, 1, 2] [True, 0, True] []
2 T [1, 1, 2] [True, 0, True] []
1 T [1, 1, 2] [False, 0, True] []
2 T [1, 1, 2] [False, 0, True] []
条件为seen[i-1]
:
0 F [1, 1, 2] [0, 0, 0] []
0 T [1, 1, 2] [True, 0, 0] []
1 T [1, 1, 2] [True, 0, 0] []
2 F [1, 1, 2] [True, 0, 0] []
0 T [1, 1, 2] [True, 0, True] []
1 T [1, 1, 2] [True, 0, True] []
2 T [1, 1, 2] [True, 0, True] []
1 F [1, 1, 2] [False, 0, False] []
0 F [1, 1, 2] [False, True, False] []
0 T [1, 1, 2] [True, True, False] []
1 T [1, 1, 2] [True, True, False] []
2 F [1, 1, 2] [True, True, False] []
1 T [1, 1, 2] [False, True, False] [[1, 1, 2]]
2 F [1, 1, 2] [False, True, False] [[1, 1, 2]]
0 F [1, 1, 2] [False, True, True] [[1, 1, 2]]
1 T [1, 1, 2] [False, True, True] [[1, 1, 2], [1, 2, 1]]
2 T [1, 1, 2] [False, True, True] [[1, 1, 2], [1, 2, 1]]
2 F [1, 1, 2] [False, False, False] [[1, 1, 2], [1, 2, 1]]
0 F [1, 1, 2] [False, False, True] [[1, 1, 2], [1, 2, 1]]
0 T [1, 1, 2] [True, False, True] [[1, 1, 2], [1, 2, 1]]
1 T [1, 1, 2] [True, False, True] [[1, 1, 2], [1, 2, 1]]
2 T [1, 1, 2] [True, False, True] [[1, 1, 2], [1, 2, 1]]
1 F [1, 1, 2] [False, False, True] [[1, 1, 2], [1, 2, 1]]
0 F [1, 1, 2] [False, True, True] [[1, 1, 2], [1, 2, 1]]
1 T [1, 1, 2] [False, True, True] [[1, 1, 2], [1, 2, 1], [2, 1, 1]]
2 T [1, 1, 2] [False, True, True] [[1, 1, 2], [1, 2, 1], [2, 1, 1]]
2 T [1, 1, 2] [False, False, True] [[1, 1, 2], [1, 2, 1], [2, 1, 1]]
且条件为!seen[i-1]
的条件为否:
0 F [1, 1, 2] [0, 0, 0] []
0 T [1, 1, 2] [True, 0, 0] []
1 F [1, 1, 2] [True, 0, 0] []
0 T [1, 1, 2] [True, True, 0] []
1 T [1, 1, 2] [True, True, 0] []
2 F [1, 1, 2] [True, True, 0] []
2 F [1, 1, 2] [True, False, False] [[1, 1, 2]]
0 T [1, 1, 2] [True, False, True] [[1, 1, 2]]
1 F [1, 1, 2] [True, False, True] [[1, 1, 2]]
2 T [1, 1, 2] [True, False, True] [[1, 1, 2], [1, 2, 1]]
1 T [1, 1, 2] [False, False, False] [[1, 1, 2], [1, 2, 1]]
2 F [1, 1, 2] [False, False, False] [[1, 1, 2], [1, 2, 1]]
0 F [1, 1, 2] [False, False, True] [[1, 1, 2], [1, 2, 1]]
0 T [1, 1, 2] [True, False, True] [[1, 1, 2], [1, 2, 1]]
1 F [1, 1, 2] [True, False, True] [[1, 1, 2], [1, 2, 1]]
2 T [1, 1, 2] [True, False, True] [[1, 1, 2], [1, 2, 1], [2, 1, 1]]
1 T [1, 1, 2] [False, False, True] [[1, 1, 2], [1, 2, 1], [2, 1, 1]]
2 T [1, 1, 2] [False, False, True] [[1, 1, 2], [1, 2, 1], [2, 1, 1]]
在所有三种情况下,执行步骤都不同。两个(偶然)的结果相同。
答案 1 :(得分:0)
当您删除seen [i-1]或!seen [i -1]时,对于其中两个或更多int数组值匹配且令人满意的输入类型
nums[i] == nums[i - 1]
if条件变为TRUE并遍历int数组,而无需添加。
依次调用以及“ permutation.add”和“ permutation.remove”,因为第一个/最后一个元素导致一个空集。使用{1,1,2}或{1,2,2}或{1,2,1}
尝试调用时的顺序Add called
Add called
Remove called
Remove called
Add called
Add called
Remove called
Remove called
[]
{2,2,2}
Add called
Remove called
[]
使用的代码:
for(int i = 0; i < nums.length; i++){
//System.out.println(seen[i]);
if(seen[i] || (i > 0 && nums[i] == nums[i - 1])){
//System.out.println("Inside if");
continue;
}
seen[i] = true;
System.out.println("Add called");
permutation.add(nums[i]);
backtrack(nums, permutation, seen);
seen[i] = false;
System.out.println("Remove called");
permutation.remove(permutation.size() - 1);
}