给定二叉树中最长的算术级数路径
给定一棵二叉树,任务是找到形成算术级数的最长路径的长度。路径可以在树的任何节点开始和结束。
例子:
Input:
Output: 5
Explanation: The longest path forming an AP is: 3->6->9->12->15
Input:
Output: 6
Explanation: The longest path forming an AP is: 2->4->6->8->10->12
方法:这里的问题是一个树节点只能支持两个 AP,一个有左孩子,另一个有右孩子。现在,要解决此问题,请按照以下步骤操作:
- 创建一个变量ans来存储最长路径的长度。
- 从根节点开始深度优先搜索,对于每个节点,找到AP的直到左孩子和右孩子的最大长度路径。
- 现在找到当前节点与其左子节点之间的差异,例如leftDiff以及当前节点与其右子节点之间的差异,例如rightDiff 。
- 现在找到左孩子中具有差异leftDiff的最长路径,例如maxLen1和右孩子中具有差异rightDiff的最长路径,例如maxLen2 。
- 如果leftDiff = (-1)*rightDiff ,则当前节点的两个分支形成一个 AP,因此将ans更改为之前的ans和maxLen1+maxLen2+1值中的最大值。
- 否则,将ans更改为之前ans值(maxLen1+1)和(maxLen2+1)中的最大值,因为只能选择两条路径之一。
- 现在返回maxLen1和maxLen2以及 AP 从当前节点到父节点的差异。
- 函数停止后打印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)