java如果条件可以是true或false,为什么需要它
我对这件事非常困惑。代码是生成给定整数列表的所有置换。一旦你这样做了,他们会添加另一个约束,即给定的输入可以有重复项,我们只需要唯一的排列
我的代码有效。。。我只是对我注意到的事情感到惊讶。在查看了代码之后,我怀疑是否有必要使用特定的条件,所以我否定了它,以查看会发生什么。在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);
}
}
}
我的问题是这怎么可能?如果代码为true或false,则代码可以工作,但完全删除它并不起作用
# 1 楼答案
当您卸下SEED[i-1]或时!参见[i-1],了解2个或更多int数组值匹配和满足的输入类型
if条件变为TRUE并在int数组上迭代,而不添加
并且“permutation.add”和“permutation.remove”被依次调用,用于产生空集的第一个/最后一个元素。使用{1,1,2}或{1,2,2}或{1,2,1}尝试调用时的序列
对于{2,2,2}
使用的代码:
# 2 楼答案
我可以确认您的代码生成相同的结果,不管是否对条件的最后一部分求反,并且在删除条件时生成不同的结果
这似乎是一个奇迹,除非你认为整个条件在一个循环中被多次评估,很可能是这三种情况(条件,带否定条件,没有条件)都有不同的处理方式和结果。我想说的是,对于条件和否定条件,可以得到相同的结果,但方式不同
这里就是这样。如果在循环中引入一些printf调试,您将看到结果是以完全不同的方式实现的。具有否定的现有条件允许完整条件在没有否定的条件之外的其他迭代中变为真。这是纯粹的机会(没有进一步研究算法),最终两者都会导致相同的结果
以下是数字
i
的执行跟踪、完整条件的结果以及此点处的中间值nums
、seen
和result
:无条件:
在条件
seen[i-1]
下:使用否定条件
!seen[i-1]
:这三种情况下的执行步骤都不同。两个(碰巧)有相同的结果