📜  在不构建树的情况下检查给定的中序和前序遍历是否对任何二叉树都有效

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

在不构建树的情况下检查给定的中序和前序遍历是否对任何二叉树都有效

给定两个数组pre[]in[]表示二叉树的前序和中序遍历,任务是在不构建树的情况下检查给定的遍历是否对任何二叉树有效。如果可能,则打印Yes 。否则,打印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)