java – 如何使用O(n)空间复杂度构建此树?
作者:互联网
问题
给定一组整数,找到总和为100,000,000的整数的子集.
解
我正在尝试构建一个包含给定集合的所有组合以及总和的树.例如,如果给定的集看起来像0,1,2,我将构建以下树,检查每个节点的总和:
{}
{} {0}
{} {1} {0} {0,1}
{} {2} {1} {1,2} {0} {2} {0,1} {0,1,2}
由于我在每个节点都保留了整数数组和总和,因此我只需要内存中树的底部(当前)级别.
问题
我当前的实现将整个树保留在内存中,因此使用了太多的堆空间.
如何更改当前的实现,以便GC处理我的上层树级?
(目前我只是在找到目标总和时抛出RuntimeException,但这显然只是为了玩游戏)
public class RecursiveSolver {
static final int target = 100000000;
static final int[] set = new int[]{98374328, 234234123, 2341234, 123412344, etc...};
Tree initTree() {
return nextLevel(new Tree(null), 0);
}
Tree nextLevel(Tree currentLocation, int current) {
if (current == set.length) { return null; }
else if (currentLocation.sum == target) throw new RuntimeException(currentLocation.getText());
else {
currentLocation.left = nextLevel(currentLocation.copy(), current + 1);
Tree right = currentLocation.copy();
right.value = add(currentLocation.value, set[current]);
right.sum = currentLocation.sum + set[current];
currentLocation.right = nextLevel(right, current + 1);
return currentLocation;
}
}
int[] add(int[] array, int digit) {
if (array == null) {
return new int[]{digit};
}
int[] newValue = new int[array.length + 1];
for (int i = 0; i < array.length; i++) {
newValue[i] = array[i];
}
newValue[array.length] = digit;
return newValue;
}
public static void main(String[] args) {
RecursiveSolver rs = new RecursiveSolver();
Tree subsetTree = rs.initTree();
}
}
class Tree {
Tree left;
Tree right;
int[] value;
int sum;
Tree(int[] value) {
left = null;
right = null;
sum = 0;
this.value = value;
if (value != null) {
for (int i = 0; i < value.length; i++) sum += value[i];
}
}
Tree copy() {
return new Tree(this.value);
}
}
解决方法:
在这里构建树所需的时间和空间绝对没有任何意义.
原因是,如果你被给予了
>树的节点
>节点的深度
>有序的输入元素数组
您可以使用O(1)操作简单地计算其父节点,左节点和右节点.当你穿越树时,你可以访问这些东西,所以你不需要任何其他东西.
标签:java,algorithm,tree,subset-sum,space-complexity 来源: https://codeday.me/bug/20190702/1353583.html