Java 递归生成子集的若干问题
因此,该算法通过使用参数i来引用A[i]来生成集合A的子集,在每个步骤中,有两个调用,一个包括A[i],另一个不包括A[i]。 当i==n时,搜索停止 所以,这是有道理的,但我不明白最后一句话是怎么说的Java 递归生成子集的若干问题,java,algorithm,subset,Java,Algorithm,Subset,因此,该算法通过使用参数i来引用A[i]来生成集合A的子集,在每个步骤中,有两个调用,一个包括A[i],另一个不包括A[i]。 当i==n时,搜索停止 所以,这是有道理的,但我不明白最后一句话是怎么说的 void search(int i, ArrayList<Integer> subset,ArrayList<Integer> A, int n){ if (i==n) System.out.println(subset); else{
void search(int i, ArrayList<Integer> subset,ArrayList<Integer> A, int n){
if (i==n) System.out.println(subset);
else{
search(i+1,subset,A,n);
subset.add(A.get(i));
search(i+1,subset,A,n);
subset.remove(subset.size()-1); /*Why do we need to do this? I am not making any function call after this*/
}
}
void搜索(int i,ArrayList子集,ArrayList A,int n){
如果(i==n)System.out.println(子集);
否则{
搜索(i+1,子集,A,n);
添加(A.get(i));
搜索(i+1,子集,A,n);
subset.remove(subset.size()-1);/*为什么我们需要这样做?在此之后我不会进行任何函数调用*/
}
}
我试图排除最后一条语句,但它会在子集中重复元素。最后一条语句的用途是什么?您拥有在所有递归级别共享的
子集的唯一实例
因此,在使用该项后,您应该返回到较低级别,并保持相同的状态subset
想象一下呼叫树
[]
[]
[2] *
[1]
[1]
[1 2]
创建子集[2](代码点*
)后,返回到第一级,并且必须生成子集[1]。但是子集
对象已经包含项2,因此如果不删除*
如果实现创建了参数的新副本,则不需要恢复状态。是否尝试使用回溯生成子集?@uneq95是的,我知道这不是最有效的方法。@MBo为您提供了正确的答案抱歉,没有得到,我的意思是最初的子集=[],当我第一次调用search时,我正在共享[],那么subset=[A[0]],我正在使用这个实例aka[A[0]],为什么还要删除一个[0]并使subset=[],再次?在此之后,我不会进行任何函数调用,我在哪里共享该实例?ArrayList subset
参数实际上是对象的地址。仅存在对象的一个副本(如果不进行深度复制)。当您在更深的递归级别修改对象时,也会在更高的级别看到更改。我加了一个例子。@Little_傻瓜你知道把答案标记为解决方案吗?