📜  给定二叉树中最长的算术级数路径

📅  最后修改于: 2022-05-13 01:56:08.447000             🧑  作者: Mango

给定二叉树中最长的算术级数路径

给定一棵二叉树,任务是找到形成算术级数的最长路径的长度。路径可以在树的任何节点开始和结束。

例子:

方法:这里的问题是一个树节点只能支持两个 AP,一个有左孩子,另一个有右孩子。现在,要解决此问题,请按照以下步骤操作:

  1. 创建一个变量ans来存储最长路径的长度。
  2. 从根节点开始深度优先搜索,对于每个节点,找到AP的直到左孩子和右孩子的最大长度路径。
  3. 现在找到当前节点与其左子节点之间的差异,例如leftDiff以及当前节点与其右子节点之间的差异,例如rightDiff
  4. 现在找到左孩子中具有差异leftDiff的最长路径,例如maxLen1和右孩子中具有差异rightDiff的最长路径,例如maxLen2
  5. 如果leftDiff = (-1)*rightDiff ,则当前节点的两个分支形成一个 AP,因此将ans更改为之前的ansmaxLen1+maxLen2+1值中的最大值。
  6. 否则,将ans更改为之前ans(maxLen1+1)(maxLen2+1)中的最大值,因为只能选择两条路径之一。
  7. 现在返回maxLen1maxLen2以及 AP 从当前节点到父节点的差异。
  8. 函数停止后打印ans

下面是上述方法的实现:

C++
// C++ code for the above approach
#include 
using namespace std;
 
// Tree Node
class Node {
public:
    int data;
    Node *left, *right;
    Node(int d)
    {
        data = d;
        left = right = NULL;
    }
};
 
// Variable to store the maximum path length
int ans = 1;
 
// Function to find the maximum length
// of a path which forms an AP
vector > maxApPath(Node* root)
{
    vector > l
        = { { INT_MAX, 0 }, { INT_MAX, 0 } },
        r = { { INT_MAX, 0 }, { INT_MAX, 0 } };
 
    // Variables to store the difference with
    // left and right nodes
    int leftDiff = INT_MAX;
    int rightDiff = INT_MAX;
 
    // If left child exists
    if (root->left) {
        l = maxApPath(root->left);
        leftDiff = (root->data)
                   - (root->left->data);
    }
 
    // If right child exists
    if (root->right) {
        r = maxApPath(root->right);
        rightDiff = (root->data)
                    - (root->right->data);
    }
 
    // Variable to store the maximum length
    // path in the left subtree in which
    // the difference between each
    // node is leftDiff
    int maxLen1 = 0;
 
    // Variable to store the maximum length
    // path in the right subtree in which
    // the difference between each
    // node is rightDiff
    int maxLen2 = 0;
 
    // If a path having the difference
    // leftDiff is found in left subtree
    if (leftDiff == l[0].first
        or l[0].first == INT_MAX) {
        maxLen1 = l[0].second;
    }
    if (leftDiff == l[1].first
        or l[1].first == INT_MAX) {
        maxLen1 = max(maxLen1, l[1].second);
    }
 
    // If a path having the difference
    // rightDiff is found in right subtree
    if (rightDiff == r[0].first
        or r[0].first == INT_MAX) {
        maxLen2 = r[0].second;
    }
    if (rightDiff == r[1].first
        or r[1].first == INT_MAX) {
        maxLen2 = max(maxLen2, r[1].second);
    }
 
    // If both left and right subtree form AP
    if (leftDiff == (-1 * rightDiff)) {
        ans = max(ans, maxLen1 + maxLen2 + 1);
    }
 
    // Else
    else {
        ans = max({ ans, maxLen1 + 1,
                    maxLen2 + 1 });
    }
 
    // Return maximum path for
    // leftDiff and rightDiff
    return { { leftDiff, maxLen1 + 1 },
             { rightDiff, maxLen2 + 1 } };
}
 
// Driver Code
int main()
{
 
    // Given Tree
    Node* root = new Node(1);
    root->left = new Node(8);
    root->right = new Node(6);
    root->left->left = new Node(6);
    root->left->right = new Node(10);
    root->right->left = new Node(3);
    root->right->right = new Node(9);
    root->left->left->right = new Node(4);
    root->left->right->right = new Node(12);
    root->right->right->right
        = new Node(12);
    root->left->left->right->right
        = new Node(2);
    root->right->right->right->left
        = new Node(15);
    root->right->right->right->right
        = new Node(11);
 
    maxApPath(root);
    cout << ans;
    return 0;
}


Java
// Java code for the above approach
class GFG{
 
// Tree Node
static class Node {
 
    int data;
    Node left, right;
    Node(int d)
    {
        data = d;
        left = right = null;
    }
};
static class pair
{
    int first, second;
    public pair(int first, int second) 
    {
        this.first = first;
        this.second = second;
    }   
}
   
// Variable to store the maximum path length
static int ans = 1;
 
// Function to find the maximum length
// of a path which forms an AP
static pair[] maxApPath(Node root)
{
    pair [] l
        = { new pair(Integer.MAX_VALUE, 0 ), new pair( Integer.MAX_VALUE, 0 ) };
                pair [] r = { new pair( Integer.MAX_VALUE, 0 ), new pair( Integer.MAX_VALUE, 0 ) };
 
    // Variables to store the difference with
    // left and right nodes
    int leftDiff = Integer.MAX_VALUE;
    int rightDiff = Integer.MAX_VALUE;
 
    // If left child exists
    if (root.left!=null) {
        l = maxApPath(root.left);
        leftDiff = (root.data)
                   - (root.left.data);
    }
 
    // If right child exists
    if (root.right!=null) {
        r = maxApPath(root.right);
        rightDiff = (root.data)
                    - (root.right.data);
    }
 
    // Variable to store the maximum length
    // path in the left subtree in which
    // the difference between each
    // node is leftDiff
    int maxLen1 = 0;
 
    // Variable to store the maximum length
    // path in the right subtree in which
    // the difference between each
    // node is rightDiff
    int maxLen2 = 0;
 
    // If a path having the difference
    // leftDiff is found in left subtree
    if (leftDiff == l[0].first
        || l[0].first == Integer.MAX_VALUE) {
        maxLen1 = l[0].second;
    }
    if (leftDiff == l[1].first
        || l[1].first == Integer.MAX_VALUE) {
        maxLen1 = Math.max(maxLen1, l[1].second);
    }
 
    // If a path having the difference
    // rightDiff is found in right subtree
    if (rightDiff == r[0].first
        || r[0].first == Integer.MAX_VALUE) {
        maxLen2 = r[0].second;
    }
    if (rightDiff == r[1].first
        || r[1].first == Integer.MAX_VALUE) {
        maxLen2 = Math.max(maxLen2, r[1].second);
    }
 
    // If both left and right subtree form AP
    if (leftDiff == (-1 * rightDiff)) {
        ans = Math.max(ans, maxLen1 + maxLen2 + 1);
    }
 
    // Else
    else {
        ans = Math.max( Math.max(ans, maxLen1 + 1),
                 maxLen2 + 1 );
    }
 
    // Return maximum path for
    // leftDiff and rightDiff
    return new pair[] { new pair(leftDiff, maxLen1 + 1 ),
            new pair( rightDiff, maxLen2 + 1 ) };
}
 
// Driver Code
public static void main(String[] args)
{
 
    // Given Tree
    Node root = new Node(1);
    root.left = new Node(8);
    root.right = new Node(6);
    root.left.left = new Node(6);
    root.left.right = new Node(10);
    root.right.left = new Node(3);
    root.right.right = new Node(9);
    root.left.left.right = new Node(4);
    root.left.right.right = new Node(12);
    root.right.right.right
        = new Node(12);
    root.left.left.right.right
        = new Node(2);
    root.right.right.right.left
        = new Node(15);
    root.right.right.right.right
        = new Node(11);
 
    maxApPath(root);
    System.out.print(ans);
}
}
 
// This code is contributed by shikhasingrajput


Python3
# Python code for the above approach
 
# Tree Node
class Node:
 
    def __init__(self, d):
        self.data = d
        self.left = self.right = None
 
# Variable to store the maximum path length
ans = 1;
 
# Function to find the maximum length
# of a path which forms an AP
def maxApPath(root):
    l = [{ "first": 10 ** 9, "second": 0 }, { "first": 10 ** 9, "second": 0 }]
    r = [{ "first": 10 ** 9, "second": 0 }, { "first": 10 ** 9, "second": 0 }];
 
    # Variables to store the difference with
    # left and right nodes
    leftDiff = 10 ** 9;
    rightDiff = 10 ** 9;
 
    # If left child exists
    if (root.left):
        l = maxApPath(root.left);
        leftDiff = (root.data) - (root.left.data);
     
    # If right child exists
    if (root.right) :
        r = maxApPath(root.right);
        rightDiff = (root.data) - (root.right.data);
     
    # Variable to store the maximum length
    # path in the left subtree in which
    # the difference between each
    # node is leftDiff
    maxLen1 = 0;
 
    # Variable to store the maximum length
    # path in the right subtree in which
    # the difference between each
    # node is rightDiff
    maxLen2 = 0;
 
    # If a path having the difference
    # leftDiff is found in left subtree
    if (leftDiff == l[0]["first"] or l[0]["first"] == 10 ** 9):
        maxLen1 = l[0]["second"];
     
    if (leftDiff == l[1]["first"] or l[1]["first"] == 10 ** 9):
        maxLen1 = max(maxLen1, l[1]["second"]);
     
 
    # If a path having the difference
    # rightDiff is found in right subtree
    if (rightDiff == r[0]["first"] or r[0]["first"] == 10 ** 9):
        maxLen2 = r[0]["second"];
     
    if (rightDiff == r[1]["first"] or r[1]["first"] == 10 ** 9):
        maxLen2 = max(maxLen2, r[1]["second"]);
     
    global ans;
 
    # If both left and right subtree form AP
    if (leftDiff == (-1 * rightDiff)):
        ans = max(ans, maxLen1 + maxLen2 + 1);
     
 
    # Else
    else:
        ans = max(ans, max(maxLen1 + 1, maxLen2 + 1));
     
 
    # Return maximum path for
    # leftDiff and rightDiff
    return [{ "first": leftDiff, "second": maxLen1 + 1 },
    { "first": rightDiff, "second": maxLen2 + 1 }];
 
 
# Driver Code
# Given Tree
root = Node(1);
root.left = Node(8);
root.right = Node(6);
root.left.left = Node(6);
root.left.right = Node(10);
root.right.left = Node(3);
root.right.right = Node(9);
root.left.left.right = Node(4);
root.left.right.right = Node(12);
root.right.right.right = Node(12);
root.left.left.right.right = Node(2);
root.right.right.right.left = Node(15);
root.right.right.right.right = Node(11);
 
maxApPath(root);
print(ans);
 
# This code is contributed by gfgking


C#
// C# code for the above approach
using System;
using System.Collections.Generic;
public class GFG {
 
  // Tree Node
  public class Node {
 
    public int data;
    public Node left, right;
 
    public Node(int d) {
      data = d;
      left = right = null;
    }
  };
 
  public class pair {
    public int first, second;
 
    public pair(int first, int second) {
      this.first = first;
      this.second = second;
    }
  }
 
  // Variable to store the maximum path length
  static int ans = 1;
 
  // Function to find the maximum length
  // of a path which forms an AP
  static pair[] maxApPath(Node root) {
    pair[] l = { new pair(int.MaxValue, 0), new pair(int.MaxValue, 0) };
    pair[] r = { new pair(int.MaxValue, 0), new pair(int.MaxValue, 0) };
 
    // Variables to store the difference with
    // left and right nodes
    int leftDiff = int.MaxValue;
    int rightDiff = int.MaxValue;
 
    // If left child exists
    if (root.left != null) {
      l = maxApPath(root.left);
      leftDiff = (root.data) - (root.left.data);
    }
 
    // If right child exists
    if (root.right != null) {
      r = maxApPath(root.right);
      rightDiff = (root.data) - (root.right.data);
    }
 
    // Variable to store the maximum length
    // path in the left subtree in which
    // the difference between each
    // node is leftDiff
    int maxLen1 = 0;
 
    // Variable to store the maximum length
    // path in the right subtree in which
    // the difference between each
    // node is rightDiff
    int maxLen2 = 0;
 
    // If a path having the difference
    // leftDiff is found in left subtree
    if (leftDiff == l[0].first || l[0].first == int.MaxValue) {
      maxLen1 = l[0].second;
    }
    if (leftDiff == l[1].first || l[1].first == int.MaxValue) {
      maxLen1 = Math.Max(maxLen1, l[1].second);
    }
 
    // If a path having the difference
    // rightDiff is found in right subtree
    if (rightDiff == r[0].first || r[0].first == int.MaxValue) {
      maxLen2 = r[0].second;
    }
    if (rightDiff == r[1].first || r[1].first == int.MaxValue) {
      maxLen2 = Math.Max(maxLen2, r[1].second);
    }
 
    // If both left and right subtree form AP
    if (leftDiff == (-1 * rightDiff)) {
      ans = Math.Max(ans, maxLen1 + maxLen2 + 1);
    }
 
    // Else
    else {
      ans = Math.Max(Math.Max(ans, maxLen1 + 1), maxLen2 + 1);
    }
 
    // Return maximum path for
    // leftDiff and rightDiff
    return new pair[] { new pair(leftDiff, maxLen1 + 1), new pair(rightDiff, maxLen2 + 1) };
  }
 
  // Driver Code
  public static void Main(String[] args) {
 
    // Given Tree
    Node root = new Node(1);
    root.left = new Node(8);
    root.right = new Node(6);
    root.left.left = new Node(6);
    root.left.right = new Node(10);
    root.right.left = new Node(3);
    root.right.right = new Node(9);
    root.left.left.right = new Node(4);
    root.left.right.right = new Node(12);
    root.right.right.right = new Node(12);
    root.left.left.right.right = new Node(2);
    root.right.right.right.left = new Node(15);
    root.right.right.right.right = new Node(11);
 
    maxApPath(root);
    Console.Write(ans);
  }
}
 
// This code is contributed by Rajput-Ji


Javascript



输出:
6

时间复杂度: O(N) 其中 N 是树中的节点数
辅助空间: O(N)