제한된 추가 공간으로 두 개의 BST 병합

난이도 하드
자주 묻는 질문 아마존 구글 Microsoft 알레그로 동네 짱
이진 검색 트리 이진 트리 나무조회수 32

문제 정책

"제한된 추가 공간으로 두 개의 BST 병합"문제는 두 개의 이진 검색 트리(BST) 두 트리의 요소를 정렬 된 순서로 인쇄해야합니다. 이는 요소가 단일 BST에서 온 것처럼 보이는 순서입니다.

입력

제한된 추가 공간으로 두 개의 BST 병합

산출

제한된 추가 공간으로 두 개의 BST 병합

4 5 6 7 9 13

설명 : 두 입력 트리를 병합하여 형성된 새 트리가 이미지에 표시됩니다. 결과 트리의 inorder traversal은 출력을 제공합니다.

제한된 추가 공간으로 두 BST를 병합하는 방법

"제한된 추가 공간으로 두 BST 병합"문제는 병합 된 트리의 순회 순회를 인쇄하도록 요청합니다. 병합 된 트리는 주어진 두 트리를 병합하여 형성됩니다. 따라서 우리는 주어진 나무를 병합하려고 시도 할 것입니다. 그러나 나무를 병합하려면 많은 오버 헤드가 필요합니다. 직접 병합하는 대신 다른 방법을 생각할 수 있습니다. 주어진 트리의 노드 값을 정렬 된 형태로 인쇄하기 만하면됩니다.

이 문제를 해결하기 위해 두 트리에서 동시에 이진 검색 트리의 반복적 인 순서 순회를 실행하려고합니다. 실행하면 가능합니다. 순서 순회. 그리고 inorder traversal에서 두 노드의 값을 비교하십시오. 그런 다음 둘 중 더 작은 노드를 인쇄하고 스택 (반복적 인 순서 순회 중에 사용되는 스택)에 더 큰 노드를 푸시합니다. 트리 중 하나에 대한 작업을 마칠 때마다 노드가 남아있는 상태에서 트리를 순회하는 순회를 실행합니다.

암호

제한된 추가 공간으로 두 BST를 병합하는 C ++ 코드

#include <bits/stdc++.h>
using namespace std;
struct node
{
    int data;
    node *left;
    node *right;
};

// returns a new node with supplied data
node* create(int data)
{
    node *temp = new node;
    temp->data = data;
    temp->left = temp->right = NULL;
    return temp;
}

void inorder(node *root)
{
    if(root){
        inorder(root->left);
        cout<<root->data<<" ";
        inorder(root->right);
    }
}

void merge(node *root1, node *root2)
{
    stack<node*> s1;node* cur1 = root1;
    stack<node*> s2;node* cur2 = root2;
    //if first tree is empty, print second tree
    if(!root1){
        inorder(root2);
        return;
    }
    // if second tree is empty, print first tree
    if(!root2){
        inorder(root2);
        return;
    }
    // print the nodes which are not yet visited or visited but not printed
    while(cur1 != NULL || !s1.empty() || cur2 != NULL || !s2.empty())
    {
        // iterative inorder
        if(cur1 != NULL || cur2 != NULL)
        {
            // Reach the leftmost node of both BSTs and push ancestors of
            // leftmost nodes to stack s1 and s2 respectively
            if(cur1 != NULL)
            {
                s1.push(cur1);
                cur1 = cur1->left;
            }
            if (cur2 != NULL)
            {
                s2.push(cur2);
                cur2 = cur2->left;
            }
        }
        else
        {
            // if anyone of the tree's current node becomes Null
            // then we need to check if stack is empty
            if(s1.empty())
            {
                while(!s2.empty())
                {
                    cur2 = s2.top();s2.pop();
                    cur2->left = NULL;
                    inorder(cur2);
                }
                return;
            }
            if(s2.empty())
            {
                while(!s1.empty())
                {
                    cur1 = s1.top();s1.pop();
                    cur1->left = NULL;
                    inorder(cur1);
                }
                return;
            }

            // compare elements at the top of both stacks
            cur1 = s1.top();s1.pop();
            cur2 = s2.top();s2.pop();

            // print the smaller of the two and push the larger element into the corresponding stack
            if(cur1->data < cur2->data)
            {
                cout<<cur1->data<<" ";
                cur1 = cur1->right;
                s2.push(cur2);
                cur2 = NULL;
            }
            else
            {
                cout<<cur2->data<<" ";
                cur2 = cur2->right;
                s1.push(cur1);
                cur1 = NULL;
            }
        }
    }
}

int main()
{
    node *root1 = NULL, *root2 = NULL;
    //first tree
    root1 = create(5);
    root1->left = create(4);
    root1->right = create(13);

    //second tree
    root2 = create(7);
    root2->left = create(6);
    root2->right = create(9);

    // Print sorted nodes of both trees
    merge(root1, root2);

    return 0;
}
4 5 6 7 9 13

제한된 추가 공간으로 두 BST를 병합하는 Java 코드

import java.util.*;
import java.lang.*;
import java.io.*;
 
class node{
  int data;
  node left;
  node right;
}
 
class Tree{
  static node root;
  static int count;
  static node create(int data){
    node tmp = new node();
    tmp.data = data;
    tmp.left = null;
    tmp.right = null;
    return tmp;
  }
  
  static void inorder(node root)
  {
      if(root != null){
          inorder(root.left);
          System.out.print(root.data+" ");
          inorder(root.right);
      }
  }
  
  static void merge(node root1, node root2)
  {
      Stack<node> s1 = new Stack<>();node cur1 = root1;
      Stack<node> s2 = new Stack<>();node cur2 = root2;
      //if first tree is empty, print second tree
      if(root1 == null){
          inorder(root2);
          return;
      }
      // if second tree is empty, print first tree
      if(root2 == null){
          inorder(root1);
          return;
      }
      // print the nodes which are not yet visited or visited but not printed
      while(cur1 != null || s1.empty() == false || cur2 != null || s2.empty() == false)
      {
          if(cur1 != null || cur2 != null)
          {
              // Reach the leftmost node of both BSTs and push ancestors of
              // leftmost nodes to stack s1 and s2 respectively
              if(cur1 != null)
              {
                  s1.push(cur1);
                  cur1 = cur1.left;
              }
              if (cur2 != null)
              {
                  s2.push(cur2);
                  cur2 = cur2.left;
              }
          }
          else
          {
              // if anyone of the tree's current node becomes Null
              // then we need to check if stack is empty
              if(s1.empty() == true)
              {
                  while (s2.empty() == false)
                  {
                      cur2 = s2.pop();
                      cur2.left = null;
                      inorder(cur2);
                  }
                  return ;
              }
              if(s2.empty() == true)
              {
                  while (s1.empty() == false)
                  {
                      cur1 = s1.pop();
                      cur1.left = null;
                      inorder(cur1);
                  }
                  return ;
              }
  
              // compare elements at the top of both stacks
              cur1 = s1.pop();
              cur2 = s2.pop();
              
              // print the smaller of the two and push the larger element into the corresponding stack
              if (cur1.data < cur2.data)
              {
                  System.out.print(cur1.data+" ");
                  cur1 = cur1.right;
                  s2.push(cur2);
                  cur2 = null;
              }
              else
              {
                  System.out.print(cur2.data+" ");
                  cur2 = cur2.right;
                  s1.push(cur1);
                  cur1 = null;
              }
          }
      }
  }
  
  public static void main(String[] args)
  {
      node root1 = null;
      node root2 = null;
      //first tree
      root1 = create(5);
      root1.left = create(4);
      root1.right = create(13);
  
      //second tree
      root2 = create(7);
      root2.left = create(6);
      root2.right = create(9);
  
      // Print sorted nodes of both trees
      merge(root1, root2);
  }

}
4 5 6 7 9 13

복잡성 분석

시간 복잡성

O (N + M), 두 트리를 동시에 순회하기 때문입니다. inorder traversal 동안 우리는 두 트리의 노드를 살펴 보았으므로 선형 시간 복잡성이 발생했습니다.

공간 복잡성

O (N + M), 보다 공식적으로 공간 복잡성은 두 나무의 높이의 합이 될 것입니다. 그러나 최악의 경우 입력은 기울어 진 트리 일 수 있으며이 경우 높이는 트리의 노드 수와 동일합니다.

Translate »