Problem p02282 (C++) — buggy submission, verdict: Runtime Error

#include <cassert>
#include <climits>
#include <fstream>
#include <iostream>
#include <stdint.h>
#include <stdio.h>
#include <vector>
using namespace std;

#define DEBUG (0)

#if DEBUG
#define DPRINTF(...)                                                           \\
  do {                                                                         \\
    printf("D(L%d) %s: ", __LINE__, __func__);                                 \\
    printf(__VA_ARGS__);                                                       \\
  } while (false)
#else
#define DPRINTF(...)
#endif // DEBUG

/* binary tree */
struct Node {
  Node() : left_(-1), right_(-1) {}

  int left_;
  int right_;
};

int findIdxOf(int val, int start, int end, const int array[]) {
  for (int i = start; i <= end; i++) {
    if (array[i] == val)
      return i;
  }

  // The val must be found between start to end index
  assert(false);
}

int reconstructTree(Node *node, int start, int end, const int preorder[],
                    const int inorder[]) {
  DPRINTF("start %d  end %d\\n", start, end);

#if DEBUG
  if (true) {
    for (int i = start; i <= end; i++) {
      if (i == start)
        DPRINTF("preorder: %d", preorder[i]);
      else
        printf(" %d", preorder[i]);
    }
    cout << endl;

    for (int i = start; i <= end; i++) {
      if (i == start)
        DPRINTF("inorder:  %d", inorder[i]);
      else
        printf(" %d", inorder[i]);
    }
    cout << endl;
  }
#endif

  if (start == end)
    return preorder[start];

  if (start > end)
    return -1;

  // Determine which one is the root node
  int root = preorder[start];
  int center = findIdxOf(root, start, end, inorder);

  DPRINTF("root %d  center  %d\\n", root, center);

  // Similarly, determine the root nodes of both the left and right trees
  // Note that pre-order array has to be alligned before dive into recursively
  // int newPreorder[center - start - 1];
  int newPreorder[center];
  for (int i = start; i < center; i++) {
    newPreorder[i] = preorder[i + 1];
    DPRINTF("newPreorder[%d] %d\\n", i, newPreorder[i]);
  }

  node[root].left_ =
      reconstructTree(node, start, center - 1, newPreorder, inorder);
  node[root].right_ = reconstructTree(node, center + 1, end, preorder, inorder);

  DPRINTF("node %d / left %d / right %d\\n", root, node[root].left_,
          node[root].right_);

  return root;
}

void traversePostorder(const Node *node, int idx, bool &first) {
  DPRINTF("idx %d\\n", idx);

  if (&node[idx] == nullptr)
    return;

  if (node[idx].left_ > -1)
    traversePostorder(node, node[idx].left_, first);

  if (node[idx].right_ > -1)
    traversePostorder(node, node[idx].right_, first);

  if (first) {
    printf("%d", idx);
    first = false;
  } else
    printf(" %d", idx);
}

int main() {
  int numOfNode;
  cin >> numOfNode;
  cin.ignore();

  int arrayOfPreorder[numOfNode];
  int arrayOfInorder[numOfNode];

  for (int i = 0; i < numOfNode; i++)
    cin >> arrayOfPreorder[i];

  for (int i = 0; i < numOfNode; i++)
    cin >> arrayOfInorder[i];

#if DEBUG
  for (int i = 0; i < numOfNode; i++) {
    if (i == 0)
      DPRINTF("%d", arrayOfPreorder[i]);
    else
      printf(" %d", arrayOfPreorder[i]);
  }
  cout << endl;

  for (int i = 0; i < numOfNode; i++) {
    if (i == 0)
      DPRINTF("%d", arrayOfInorder[i]);
    else
      printf(" %d", arrayOfInorder[i]);
  }
  cout << endl;
#endif

  Node *nodes = new Node[numOfNode + 1];

  int start = 0;
  int end = numOfNode - 1;
  int rootIdx =
      reconstructTree(nodes, start, end, arrayOfPreorder, arrayOfInorder);

  bool first = true;
  traversePostorder(nodes, rootIdx, first);
  cout << endl;

  delete[] nodes;

  return 0;
}


Error: WA

Fixed submission:

#include <cassert>
#include <climits>
#include <fstream>
#include <iostream>
#include <stdint.h>
#include <stdio.h>
#include <vector>
using namespace std;

#define DEBUG (0)

#if DEBUG
#define DPRINTF(...)                                                           \\
  do {                                                                         \\
    printf("D(L%d) %s: ", __LINE__, __func__);                                 \\
    printf(__VA_ARGS__);                                                       \\
  } while (false)
#else
#define DPRINTF(...)
#endif // DEBUG

/* binary tree */
struct Node {
  Node() : left_(-1), right_(-1) {}

  int left_;
  int right_;
};

int findIdxOf(int val, int start, int end, const int array[]) {
  for (int i = start; i <= end; i++) {
    if (array[i] == val)
      return i;
  }

  // The val must be found between start to end index
  assert(false);
}

int reconstructTree(Node *node, int start, int end, const int preorder[],
                    const int inorder[]) {
  DPRINTF("start %d  end %d\\n", start, end);

#if DEBUG
  if (true) {
    for (int i = start; i <= end; i++) {
      if (i == start)
        DPRINTF("%d", preorder[i]);
      else
        printf(" %d", preorder[i]);
    }
    cout << endl;

    for (int i = start; i <= end; i++) {
      if (i == start)
        DPRINTF("%d", inorder[i]);
      else
        printf(" %d", inorder[i]);
    }
    cout << endl;
  }
#endif

  if (start == end)
    return preorder[start];

  if (start > end)
    return -1;

  // Determine which one is the root node
  int root = preorder[start];
  int center = findIdxOf(root, start, end, inorder);

  DPRINTF("root %d  center  %d\\n", root, center);

  // Similarly, determine the root nodes of both the left and right trees
  // Note that pre-order array has to be alligned before dive into recursively
  // int newPreorder[center - start - 1];
  int newPreorder[center];
  for (int i = start; i < center; i++) {
    newPreorder[i] = preorder[i + 1];
    DPRINTF("newPreorder[%d] %d\\n", i, newPreorder[i]);
  }

  node[root].left_ =
      reconstructTree(node, start, center - 1, newPreorder, inorder);
  node[root].right_ = reconstructTree(node, center + 1, end, preorder, inorder);

  return root;
}

void traversePostorder(const Node *node, int idx, bool &first) {
  // DPRINTF("idx %d\\n", idx);

  if (&node[idx] == nullptr)
    return;

  if (node[idx].left_ > -1)
    traversePostorder(node, node[idx].left_, first);

  if (node[idx].right_ > -1)
    traversePostorder(node, node[idx].right_, first);

  if (first) {
    printf("%d", idx);
    first = false;
  } else
    printf(" %d", idx);
}

int main() {
  int numOfNode;
  cin >> numOfNode;
  cin.ignore();

  int arrayOfPreorder[numOfNode];
  int arrayOfInorder[numOfNode];

  for (int i = 0; i < numOfNode; i++)
    cin >> arrayOfPreorder[i];

  for (int i = 0; i < numOfNode; i++)
    cin >> arrayOfInorder[i];

#if DEBUG
  for (int i = 0; i < numOfNode; i++) {
    if (i == 0)
      DPRINTF("%d", arrayOfPreorder[i]);
    else
      printf(" %d", arrayOfPreorder[i]);
  }
  cout << endl;

  for (int i = 0; i < numOfNode; i++) {
    if (i == 0)
      DPRINTF("%d", arrayOfInorder[i]);
    else
      printf(" %d", arrayOfInorder[i]);
  }
  cout << endl;
#endif

  Node *nodes = new Node[numOfNode];

  int start = 0;
  int end = numOfNode - 1;
  int rootIdx =
      reconstructTree(nodes, start, end, arrayOfPreorder, arrayOfInorder);

  bool first = true;
  traversePostorder(nodes, rootIdx, first);
  cout << endl;

  delete[] nodes;

  return 0;
}