C++ 求最大可能三角形弦的和

C++ 求最大可能三角形弦的和,c++,data-structures,C++,Data Structures,我有一棵二叉树 2 / \ 3 4 / \ \ 5 1 8 / \ / \ 1 6 9 2 \ 4 我想找到给定树中节点的最大可能三角形和弦信息和(在任意两个叶子和同时具有左和右子节点的节点之间) 一个三角形和弦将是 对于三角弦: 想象一下任意两片叶子之间的一条线,向上走向根部,找到一个共同的父

我有一棵二叉树

         2
       /   \
      3     4
     / \     \
    5   1     8
   / \       / \
  1   6     9   2
                 \
                  4
我想找到给定树中节点的
最大可能三角形和弦信息和
(在任意两个叶子和同时具有左和右子节点的节点之间)

一个三角形和弦将是

对于三角弦:

想象一下任意两片叶子之间的一条线,向上走向根部,找到一个共同的父母(可以是父母、祖父母、外祖父母,甚至是根部本身)。当向上移动时,对于每一片叶子(对于任何一片叶子,我们只能向上向左…左右…等等)意味着(左叶仅向上移动
右叶仅向上移动
右叶仅向上移动…现在我们得到一个三角形。
一个边可能包含任意数量的节点/链接
。现在,如果该
三角形形状不包含任何额外的内部分支
。该三角形形状将是一个三角形弦

请记住,
每个叶节点也始终是三角形弦
(如果二叉树没有任何三角形弦,这只是创建默认情况)

现在

我们需要
返回最大总数。

    If we do not have triangular shaped chord.. 
then we have to return the leaf with maximum info.
比如说

   8                    
  / \
 2   3
      \
       3
是三角形和弦

  8                     
  / \                   
 2   3
  \   \
   4   1
    8                    
   / \
  2   3
 /     \
4       3
只有具有单个节点4的子树将是最大三角形弦(因为其总和大于具有单个节点1的另一个三角形弦),而不是整个树将是三角形弦

  8                     
  / \                   
 2   3
  \   \
   4   1
    8                    
   / \
  2   3
 /     \
4       3
是三角形和弦

  8                     
  / \                   
 2   3
  \   \
   4   1
    8                    
   / \
  2   3
 /     \
4       3
所以第一行问题的第一棵树的解是

8+9+2+4 = 23
我被这个问题严重困住了

我有一个粗略的方法

我将递归地调用leftchild作为子树的根,并找到左最大三角弦和 然后将rightchild作为子树的根

添加leftmax和rightmax的max,以及addtorood节点并返回

在C++ MyCube中,P>是:

int maxtri(node* n) 
{
  if(n) 
  {
    lsum = maxtri(n->left);
    rsum = maxtri(n->right);
    k = maxof(lsum,rsum);
    return (n->info + k);
  }
}
编辑:我的另一个递归方法

int l =0, r =0;
int maxtri(node* n)
{
 if (n == NULL) return 0;
 if (!(n->left) && !(n->right)) return n->info;
 if ((n->left) && (n->right))
 {
  l = maxtri(n->left);
  r = maxtri(n->right);
 }
 if ((n->left) && !(n->right)) 
 {  
  l = l + maxtri(n->left);
 }
 if (!(n->left) && (n->right)) 
 {
  r = r + maxtri(n->right);
 }
 return (l+r+n->info);
}
我怀疑我的方法


有人能给出另一种解决方案吗?

据我所知,我为我的方法编写了伪代码

Max = min_value; //possibly 0 if no negative value is allowed for nodes.
sum = 0;
for each node in the tree
    temp = node;
    sum+= temp->data  //collects data at the current level, the current level may be leaf too.
    Until temp->left is not null, // Traversing uni-directionally to the left most deep and collecting data.
       temp = temp->left
       sum+=temp->data 
    Until temp->right is not null,  // Traversing uni-directionally to the right most deep and collecting data.
       temp = temp->right
       sum+= temp->data 

    if(sum > Max)
      Max = sum;

    sum = 0;  



print Max;
这个逻辑是什么:
对于每个节点遍历左边和右边的部分,如果你找到任何分支,那么不要在计算中考虑这个节点,否则要考虑这个问题。此外,对于计算节点,应该有左右节点,或者应该是叶节点。

注意:我没有正确测试它,但我相信它应该工作

// Node by Node traverse the tree  

void addSum(Node *head, vector<int>& sum)
{
if (head == NULL)
    return;
else {
    int s = traverseThisNode(head);
    sum.push_back(s); // Add to vector
    addSum(head->left, sum);
    addSum(head->right, sum);
}
}

// For each node traverse left & right  

int traverseThisNode(Node *head)
{
if (head && head->left && head->right) {
    Node *temp = head;  // To traverse right portion of this node
    int sum = head->value;
    while(head->left) {   // Traverse right
        head = head->left;
        sum = sum + head->value;
        if (head->right) {  // Condition to check if there is any branching
            sum = 0;
            break;
        }
    }
    while(temp->right && sum != 0) {  // Traverse Right now
        temp = temp->right;
        sum = sum + temp->value;
        if (temp->left) { // Condition to check if there is any branching
            sum = 0;
            break;
        }
    }

    return sum;
} else if (head && !head->left && !head->right) {
    return head->value;   // To add leaf node
}
return 0;
}

Now you have vector containing all the value of triangular in the tree, traverse it and   
find the maximum.
int maximum() 
{
  // Traverse the vector "sum" & find the maximum
}
//逐节点遍历树
无效加法和(节点*头、向量和和和)
{
if(head==NULL)
返回;
否则{
int s=遍历此节点(头部);
sum.push_back(s);//添加到向量
addSum(head->left,sum);
addSum(head->right,sum);
}
}
//对于每个节点,向左和向右遍历
int traverseThisNode(节点*头)
{
如果(头部和头部->左侧和头部->右侧){
Node*temp=head;//遍历此节点的右侧部分
整数和=头->值;
而(头部->左侧){//向右移动
头部=头部->左侧;
总和=总和+总成本->价值;
if(head->right){//检查是否有分支的条件
总和=0;
打破
}
}
而(temp->right&&sum!=0){//立即遍历
温度=温度->右侧;
总和=总和+温度->值;
if(temp->left){//检查是否有分支的条件
总和=0;
打破
}
}
回报金额;
}否则如果(头部和头部->左侧和头部->右侧){
返回head->value;//添加叶节点
}
返回0;
}
现在有了包含树中三角形所有值的向量,遍历它并
找到最大值。
int最大值()
{
//遍历向量“sum”&找到最大值
}

这是家庭作业吗?你试过什么?给我们看一些代码。我想在开始编码之前找到正确的方法。所以我给出了我的粗略方法。以及粗略编码。现在请纠正我的方法。这不是StackOverflow的真正目的,请阅读。另外,那是哪种编程语言?我遇到了一个问题。我给出了我的粗略方法ach和我发现它不正确。所以我在这里问这个问题是为了得到更好的答案。我没有写一个“单行线”问题,没有任何冒犯性的东西,…相反,我给出了正确的解释,尽了全力让它清楚。它有什么错。为什么我被否决了。我是一个新手,我正在寻求我的前辈们的帮助No StaskOffo..不做任何下注投票……我不在乎……但如果你们中任何人发表任何回答我都会很感激……KOKA回答了你的问题吗?考虑一个完整的二元树…现在最左边和最右边的一对叶子将永远把树的根看作共同的父……这是不寻常的,形成一个三角形的和弦,因为总是有内部分支(对于3或更多的高度),至少在完全二叉树的情况下。我想你没有考虑内部分支。你的解决方案的时间复杂度=O(nLogn+Max VCurror())我们可以使用变量max并将max结果存储到遍历中,而不是使用向量和外部计算最大元素。。最后,我们将使用max作为最终返回结果。@koka:是的,我们可以对求最大值进行一些优化。.我更专注于在树中首先求出三角形,所以我不想多考虑这一部分h:)