在不构建树的情况下检查给定的中序和前序遍历是否对任何二叉树都有效
给定两个数组pre[]和in[]表示二叉树的前序和中序遍历,任务是在不构建树的情况下检查给定的遍历是否对任何二叉树有效。如果可能,则打印Yes 。否则,打印No 。
例子:
Input: pre[] = {1, 2, 4, 5, 7, 3, 6, 8}, in[] = {4, 2, 5, 7, 1, 6, 8, 3}
Output: Yes
Explanation:
Both traversals are valid for the following binary tree:
1
/ \
2 3
/ \ /
4 5 6
\ \
7 8
Input: pre[] = {1, 2, 69, 5, 7, 3, 6, 8}, in[] = {4, 2, 5, 7, 1, 6, 8, 3}
Output: No
方法:想法是使用类似的技术从中序和前序遍历构建二叉树,除了不构建树,而是检查该树(子树)的当前中序遍历和当前前序索引是否有效或不在每个递归调用中。
下面是上述方法的实现:
C++
// C++ program for the above approach
#include
using namespace std;
// C++ program to check if given inorder
// and preorder traversals of size N are
// valid for a binary tree or not
bool checkInorderPreorderUtil(
int inStart, int inEnd,
int& preIndex, int preorder[],
unordered_map& inorderIndexMap)
{
if (inStart > inEnd)
return true;
// Build the current Node
int rootData = preorder[preIndex];
preIndex++;
// If the element at current Index
// is not present in the inorder
// then tree can't be built
if (inorderIndexMap.find(rootData)
== inorderIndexMap.end())
return false;
int inorderIndex = inorderIndexMap[rootData];
// If the inorderIndex does not fall
// within the range of the inorder
// traversal of the current tree
// then return false
if (!(inStart <= inorderIndex
&& inorderIndex <= inEnd))
return false;
int leftInorderStart = inStart;
int leftInorderEnd = inorderIndex - 1;
int rightInorderStart = inorderIndex + 1;
int rightInorderEnd = inEnd;
// Check if the left subtree can be
// built from the inorder traversal
// of the left subtree and preorder
if (!checkInorderPreorderUtil(
leftInorderStart, leftInorderEnd,
preIndex, preorder, inorderIndexMap))
return false;
// Check if the left subtree can be
// built from the inorder traversal
// of the left subtree and preorder
else
return checkInorderPreorderUtil(
rightInorderStart, rightInorderEnd,
preIndex, preorder, inorderIndexMap);
}
// Function to check for the validation of
// inorder and preorder
string checkInorderPreorder(
int pre[], int in[], int n)
{
unordered_map inorderIndexMap;
for (int i = 0; i < n; i++)
inorderIndexMap[in[i]] = i;
int preIndex = 0;
if (checkInorderPreorderUtil(
0, n - 1, preIndex,
pre, inorderIndexMap)) {
return "Yes";
}
else {
return "No";
}
}
// Driver Code
int main()
{
int pre[] = { 1, 2, 4, 5, 7, 3, 6, 8 };
int in[] = { 4, 2, 5, 7, 1, 6, 8, 3 };
int N = sizeof(pre) / sizeof(pre[0]);
cout << checkInorderPreorder(pre, in, N);
return 0;
}
Java
// Java program to check if given inorder
// and preorder traversals of size N are
// valid for a binary tree or not
import java.util.*;
class GFG
{
static int preIndex;
static HashMap inorderIndexMap = new HashMap();
static boolean checkInorderPreorderUtil(
int inStart, int inEnd,
int preorder[])
{
if (inStart > inEnd)
return true;
// Build the current Node
int rootData = preorder[preIndex];
preIndex++;
// If the element at current Index
// is not present in the inorder
// then tree can't be built
if (!inorderIndexMap.containsKey(rootData))
return false;
int inorderIndex = inorderIndexMap.get(rootData);
// If the inorderIndex does not fall
// within the range of the inorder
// traversal of the current tree
// then return false
if (!(inStart <= inorderIndex
&& inorderIndex <= inEnd))
return false;
int leftInorderStart = inStart;
int leftInorderEnd = inorderIndex - 1;
int rightInorderStart = inorderIndex + 1;
int rightInorderEnd = inEnd;
// Check if the left subtree can be
// built from the inorder traversal
// of the left subtree and preorder
if (!checkInorderPreorderUtil(
leftInorderStart, leftInorderEnd,preorder))
return false;
// Check if the left subtree can be
// built from the inorder traversal
// of the left subtree and preorder
else
return checkInorderPreorderUtil(
rightInorderStart, rightInorderEnd,
preorder);
}
// Function to check for the validation of
// inorder and preorder
static String checkInorderPreorder(
int pre[], int in[], int n)
{
//HashMap inorderIndexMap = new HashMap();
for (int i = 0; i < n; i++)
inorderIndexMap.put(in[i], i);
preIndex = 0;
if (checkInorderPreorderUtil(
0, n - 1,
pre)) {
return "Yes";
}
else {
return "No";
}
}
// Driver Code
public static void main(String[] args)
{
int pre[] = { 1, 2, 4, 5, 7, 3, 6, 8 };
int in[] = { 4, 2, 5, 7, 1, 6, 8, 3 };
int N = pre.length;
System.out.print(checkInorderPreorder(pre, in, N));
}
}
// This code is contributed by shikhasingrajput
Python3
# Python program to check if given inorder
# and preorder traversals of size N are
# valid for a binary tree or not
def checkInorderPreorderUtil(inStart, inEnd, preIndex, preorder, inorderIndexMap):
if (inStart > inEnd):
return True
# Build the current Node
rootData = preorder[preIndex]
preIndex += 1
# If the element at current Index
# is not present in the inorder
# then tree can't be built
if (rootData in inorderIndexMap):
return False
inorderIndex = inorderIndexMap[rootData]
# If the inorderIndex does not fall
# within the range of the inorder
# traversal of the current tree
# then return false
if ((inStart <= inorderIndex and inorderIndex <= inEnd)==False):
return False
leftInorderStart = inStart
leftInorderEnd = inorderIndex - 1
rightInorderStart = inorderIndex + 1
rightInorderEnd = inEnd
# Check if the left subtree can be
# built from the inorder traversal
# of the left subtree and preorder
if(checkInorderPreorderUtil(leftInorderStart,leftInorderEnd,preIndex,preorder,inorderIndexMap)==False):
return False
# Check if the left subtree can be
# built from the inorder traversal
# of the left subtree and preorder
else:
return checkInorderPreorderUtil(rightInorderStart, rightInorderEnd,preIndex, preorder, inorderIndexMap)
# Function to check for the validation of
# inorder and preorder
def checkInorderPreorder(pre, inv,n):
inorderIndexMap = {}
for i in range(n):
inorderIndexMap[inv[i]] = i
preIndex = 0
if (checkInorderPreorderUtil(0, n - 1, preIndex,pre, inorderIndexMap)):
return "No"
else:
return "Yes"
# Driver Code
if __name__ == '__main__':
pre = [1, 2, 4, 5, 7, 3, 6, 8]
inv = [4, 2, 5, 7, 1, 6, 8, 3]
N = len(pre)
print(checkInorderPreorder(pre, inv, N))
# This code is contributed by ipg2016107.
C#
// C# program to check if given inorder
// and preorder traversals of size N are
// valid for a binary tree or not
using System;
using System.Collections.Generic;
public class GFG
{
static int preIndex;
static Dictionary inorderIndexMap = new Dictionary();
static bool checkInorderPreorderUtil(
int inStart, int inEnd,
int []preorder)
{
if (inStart > inEnd)
return true;
// Build the current Node
int rootData = preorder[preIndex];
preIndex++;
// If the element at current Index
// is not present in the inorder
// then tree can't be built
if (!inorderIndexMap.ContainsKey(rootData))
return false;
int inorderIndex = inorderIndexMap[rootData];
// If the inorderIndex does not fall
// within the range of the inorder
// traversal of the current tree
// then return false
if (!(inStart <= inorderIndex
&& inorderIndex <= inEnd))
return false;
int leftInorderStart = inStart;
int leftInorderEnd = inorderIndex - 1;
int rightInorderStart = inorderIndex + 1;
int rightInorderEnd = inEnd;
// Check if the left subtree can be
// built from the inorder traversal
// of the left subtree and preorder
if (!checkInorderPreorderUtil(
leftInorderStart, leftInorderEnd,preorder))
return false;
// Check if the left subtree can be
// built from the inorder traversal
// of the left subtree and preorder
else
return checkInorderPreorderUtil(
rightInorderStart, rightInorderEnd,
preorder);
}
// Function to check for the validation of
// inorder and preorder
static String checkInorderPreorder(
int []pre, int []inn, int n)
{
// Dictionary inorderIndexMap = new Dictionary();
for (int i = 0; i < n; i++)
inorderIndexMap.Add(inn[i], i);
preIndex = 0;
if (checkInorderPreorderUtil(
0, n - 1,
pre)) {
return "Yes";
}
else {
return "No";
}
}
// Driver Code
public static void Main(String[] args)
{
int []pre = { 1, 2, 4, 5, 7, 3, 6, 8 };
int []inn = { 4, 2, 5, 7, 1, 6, 8, 3 };
int N = pre.Length;
Console.Write(checkInorderPreorder(pre, inn, N));
}
}
// This code is contributed by 29AjayKumar
Javascript
输出:
Yes
时间复杂度: O(N)
辅助空间: O(N)