Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/144.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 交替符号二叉树_C++_Algorithm_Tree - Fatal编程技术网

C++ 交替符号二叉树

C++ 交替符号二叉树,c++,algorithm,tree,C++,Algorithm,Tree,给定一个具有以下属性的二叉树,该二叉树的所有叶节点都是正号(+),然后该路径的符号交替到根。因此,根据路径,节点可以有多个符号 现在我们需要求出每条路径的和以及树的和。 这里的问题是确定每个节点的符号,该符号由其底层路径中的叶节点控制 我可以想出一个时间复杂度为O(n)且空间为O(n)的解决方案,在这个解决方案中,我可以将每条路径保存为从根到底的向量遍历,然后从叶节点开始确定每个节点的符号,从而计算每条路径的和 现在谁能提出任何改进的方法,空间复杂度为O(1)。 首选任何递归或迭代方法 我希望

给定一个具有以下属性的二叉树,该二叉树的所有叶节点都是正号(+),然后该路径的符号交替到根。因此,根据路径,节点可以有多个符号

现在我们需要求出每条路径的和以及树的和。

这里的问题是确定每个节点的符号,该符号由其底层路径中的叶节点控制

我可以想出一个时间复杂度为O(n)且空间为O(n)的解决方案,在这个解决方案中,我可以将每条路径保存为从根到底的向量遍历,然后从叶节点开始确定每个节点的符号,从而计算每条路径的和

现在谁能提出任何改进的方法,空间复杂度为O(1)。 首选任何递归或迭代方法

我希望我已经清楚地解释了这个问题。不过,如果有任何疑问,我会很快补充更多细节

编辑:二叉树是这样存储和实现的&不是在一个数组中

struct node
{
    int data;
    struct node* left;
    struct node* right;
};

struct node* newNode(int data)

{
  struct node* node = (struct node*)
                       malloc(sizeof(struct node));
  node->data = data;
  node->left = NULL;
  node->right = NULL;

  return(node);
}

int main()
{
  struct node *root = newNode(1);
  root->left        = newNode(2);
  root->right       = newNode(3);
  root->left->left  = newNode(4);
  root->left->right = newNode(5); 
}
在任何情况下都无法保存存储树所需的空间。请不要动手做这棵树。假设您获得了树的根节点,并且已经构建了树


我指的是运行特定算法来回答问题所需的额外空间。

好的,因此,如果我们能够从下到上遍历树,我们可以轻松获得具有O(1)额外空间和O(n^2)时间复杂度的解:

for(every leaf in tree){

   Node node = leaf;
   int total = 0;
   int sign = 1;
   while(node != null){
       total += sign*node.value;
       node = node.parent;
       sign *= -1; 
   }
   print total;
}
对于时间复杂度为O(n)的自顶向下遍历,为了获得O(1)个额外空间,需要一个更复杂的算法

Node node = root;
Node last = null;
int total = 0;
int sign = 1;
boolean back = false;
while(node != null){
     total += sign*node.value;
     if(node is leaf){
        if(sign == 1)
           print total;//Need to check if sign is not positive
        else
           print -total;
        back = true;//If this is leaf, we need to go back
        total -= sign*node.value;
        last = node;
        node = node.parent;
     }else if(back){
        if(last is left child){
           back = false;
           node = node.rightChild;
        }else{//We need to continue to go back if we are going back and this is right child 
           last = node;
           total -= sign*node.value;
           node = node.parent;
        } 
     }else{
        total += sign*node.value;
        node = node.leftChild;
     }
     sign *= -1; 

}
注意

  • 使用堆栈的递归自上而下遍历或迭代遍历很容易产生O(n)空间复杂性,所以要小心

  • 如果每个节点中没有父链接,我们就无法解决这个问题,因为在这种情况下,需要一个类似堆栈的数据结构来遍历树

更新:

因为我们可以更改树中节点的值,所以我们可以修改节点的左链接以将其用作到父节点的链接

Node node = root;
Node last = null;
int total = 0;
int sign = 1;
boolean back = false;
while(node != null){
     total += sign*node.value;
     if(node is leaf){
        if(sign == 1)
           print total;//Need to check if sign is not positive
        else
           print -total;
        back = true;//If this is leaf, we need to go back
        total -= sign*node.value;
        Node tmp = last;//For leaf node, we can just use variable last
        last = node;
        node = tmp;
     }else if(back){
        if(last is not right child){
           back = false;
           last = node;
           node = node.rightChild;
        }else{//We need to continue to go back if we are going back and this is right child 
           last = node;
           total -= sign*node.value;
           node = node.leftChild;
        } 
     }else{
        total += sign*node.value;
        Node tmp = node.leftChild;
        node.leftChild = last;
        last = node;
        node = tmp;
     }
     sign *= -1; 

}

你需要最大化总和吗?无法理解决定非叶节点符号的标准。不,我们不需要最大化和。标准很简单:叶节点是正号&然后该路径的符号交替到根。因此,一个节点可以有多个符号,这取决于路径。你说的O(1)是什么意思,你至少要穿过节点一次。你能解释一下你打算如何在O(n)时间和空间中完成它吗?@sasha:我说的是O(1)空间而不是O(1)时间O(1)空间意味着不使用任何额外的空间。我将使用路径数组path[]来存储当前根到叶的路径。以自上而下的方式从根部移动到所有叶片。遍历时,将当前路径中所有节点的数据存储在数组路径[]中。当我们到达叶节点时,我们可以停止。
Node node = root;
Node last = null;
int total = 0;
int sign = 1;
boolean back = false;
while(node != null){
     total += sign*node.value;
     if(node is leaf){
        if(sign == 1)
           print total;//Need to check if sign is not positive
        else
           print -total;
        back = true;//If this is leaf, we need to go back
        total -= sign*node.value;
        Node tmp = last;//For leaf node, we can just use variable last
        last = node;
        node = tmp;
     }else if(back){
        if(last is not right child){
           back = false;
           last = node;
           node = node.rightChild;
        }else{//We need to continue to go back if we are going back and this is right child 
           last = node;
           total -= sign*node.value;
           node = node.leftChild;
        } 
     }else{
        total += sign*node.value;
        Node tmp = node.leftChild;
        node.leftChild = last;
        last = node;
        node = tmp;
     }
     sign *= -1; 

}