在O(1)中构造二叉树?

时间:2018-03-26 23:20:11

标签: algorithm time-complexity binary-tree

我的朋友在接受采访时被问到这个问题:

  

O(1)中生成一个有限但任意大的二叉树。方法generate()应返回一个二进制树,其大小无限但有限。

我们在面试后很长时间都对它进行了思考,但我们最多只能提出O(n)解决方案。

我们如何在O(1)中生成?它甚至可能吗?还有更多的东西吗?

5 个答案:

答案 0 :(得分:7)

这是非常不明确的,但他们想要他们想要的东西:

def generate():
    if coinflip():
        return Node()
    return Node(left=None, right=generate())

O(1)预期运行时,无界返回树大小(以及无限可能的运行时,包括永远以概率0运行)。我们随机决定是否继续以每次50%的概率使树更深。

答案 1 :(得分:1)

这是O(1)运行时和无界限。树的内容在generate()期间确定。

#include <stdlib.h>
#include <string>

class node {
  std::string _value;
  unsigned int _left_seed;
  unsigned int _right_seed;
  bool _right_exists;
  bool _left_exists;

public:
  inline node(unsigned int seed,std::string const& value)
  {
    _value = value;
    _left_seed = rand_r(&seed);
    _right_seed = rand_r(&seed);
    _left_exists = true; //rand_r(&seed)>5; // depends on what 'unbounded' means
    _right_exists = true; //rand_r(&seed)>5;
  }

  inline node *get_left()
  {
    if (!_left_exists) return NULL;

    unsigned int tseed = _left_seed;
    char ch = '0' + rand_r(&tseed) % 5;

    return new node(tseed,std::string(_value) + ch);
  }

  inline node *get_right()
  {
    if (!_right_exists) return NULL;

    unsigned int tseed = _right_seed;
    char ch = '5' + rand_r(&tseed) % 5;

    return new node(tseed,std::string(_value) + ch);
  }

  inline const std::string& get_value()
  {
    return(_value);
  }
};

static node *generate()
{
  std::string str("");
  return new node(random(),str);
}

答案 2 :(得分:0)

https://www.dailycodingproblem.com/blog/big-tree/

import random

class Node:
    def __init__(self, val, left=None, right=None):
        self.val = val
        self.left = left
        self.right = right

def generate():
    root = Node(0)

if random.random() < 0.5:
    root.left = generate()
if random.random() < 0.5:
    root.right = generate()

return root

答案 3 :(得分:0)

生成一个小于可用内存大小的随机数。 然后,在本地内存中选择该长度的任何字节数组。

恭喜!您刚刚创建了一个随机的二叉树。二进制树的一种表示形式是数组。 参见:https://en.wikipedia.org/wiki/Binary_tree#Arrays

答案 4 :(得分:0)

这是愚蠢面试问题的一个很好的例子。

解决办法是生成单个节点并返回。这棵树的特殊属性是 getLeft() 和 getRight() 是一个外观,并在调用函数时生成节点,而不是预先创建所有节点。

public static void main(String args[]) {
  Node root = new Node(); // O(1)
}

public class Node {
  private Node left, right;
  private boolean isLeftEvaluated = false, isRightEvaluated = false;

  public Node getLeft() {
    if (! isLeftEvaluated) {
      left = new Node();
    }

    isLeftEvaluated = true;
    return left;
  }

  public Node getRight() {
    if (! isRightEvaluated) {
      right = new Node();
    }

    isRightEvaluated = true;
    return right;
  }
}

在编程方面有丰富经验的人都不会想到这种具有这种未指定要求的解决方案。