【问题标题】:Design a O(1) data structure设计一个 O(1) 的数据结构
【发布时间】:2018-03-27 10:43:35
【问题描述】:

我将如何实现一个在恒定时间内支持以下内容的数据结构。我在求职面试中遇到了这个问题,以下是我的解决方案。请检查我的方法,或者建议一种更好的替代方法(如果有的话)。

////////////////////////////////////////////////////////////////
// Implement a container that have the following methods:
// Java:
//     public class Container<E>
//     {
//         // data memebers
//         ...
//         public Container();
//             // constructor
//             // Complexity: Constant
//
//         public int size();
//              // return the total number of elements in the container
//              // Complexity: Constant
//
//         public E get(int index);
//              // get an element from the container by its index
//              // Complexity: Constant
//
//         public void set(int index, E element);
//              // set an element in the container by its index. index >= 0 && index < size()
//              // Complexity: Constant
//
//         public void add_front (E element);
//              // add a new element to the front of the container i.e. its index is 0
//              // Complexity: Constant (amortized time)
//
//         public void remove_front ();
//              // remove the element at the front of the container
//              // Complexity: Constant
//
//         public void add_back (E element);
//              // add a new element to the back of the container i.e. its index is size()
//              // Complexity: Constant (amortized time)
//
//         public void remove_back ();
//              // remove the element at the back of the container
//              // Complexity: Constant
//     }
//
// Examples:
//   at beginning   => []

//   add_front(0)   => [0]
//   add_front(-1)  => [-1, 0]
//   add_back(1)    => [-1, 0, 1]
//   add_back(2)    => [-1, 0, 1, 2]
//   get(0)         => -1
//   get(3)         => 2
//   set(3, 8)      => [-1, 0, 1, 8]
//   remove_front() => [0, 1, 8]
//   remove_back()  => [0, 1]
////////////////////////////////////////////////////////////////

我的方法 使用 Hashtable 存储值。 哈希表存储 = new Hashtable(); 有两个变量frontback,分别表示数据结构存储范围的开始和结束。

  1. add_front(E 元素)
low--;
storage.put(low, element);
  1. add_back(E 元素)

高++; storage.put(high, element);

  1. public void remove_front();

低++;

  1. public void remove_back ();

高--;

  1. public E get(int index);

索引 = 索引低;返回 storage.get(index);

  1. public void set(int index, E element);

索引 = 索引低; storage.put(index, element);

  1. public int size();

返回高-低+1;

【问题讨论】:

  • 如果你已经有一个可行的解决方案,你应该把它移到Code Review
  • 似乎更像是Code Review 的问题,而不是 Stack Overflow。请注意,哈希表并不是真正的O(1)(尽管实际上它们工作得很好,并且它们的平均情况确实是O(1),但在最坏的情况下它们是O(n))。
  • 哈希表并不意味着元素按照插入的顺序进行排序,那么如何使add_frontadd_back 保持最新?我认为您需要一个哈希表和一个链表,一些查询/操作由其中一个处理,一些由另一个处理,并且每次操作它们时都需要保持同步(并且同步需要花费 O( 1)).
  • @shmosel 移动了此代码审查 codereview.stackexchange.com/questions/177997/…
  • 你的方法几乎行得通,但是你从哈希表得到的 O(1) expected 时间与 O(1) amoritized 时间不同i> 要求的时间。但是,即使它完全正确,它也不会是一个非常有效的实现。您想要的东西在 Java 中称为 ArrayDeque。您可能需要查看源代码。

标签: java algorithm data-structures big-o hashtable


【解决方案1】:

由于 add_front() 和 add_back() 的复杂度需要摊销常数,而 remove_front() 和 remove(back) 后不需要内存效率,可以使用数组!它们比哈希表更简单,并且运行时复杂度没有“高概率”。

你可以从一个大小为 3 的数组开始,将第一个元素放在中间,这样你就有了一个 add_front 和一个 add_back 的空间。然后当它溢出时,只需将元素移动到一个大小为 6 的数组中间。一般来说,每次溢出时你都会将数组大小加倍。

您显然需要通过数据结构中的一些整数变量来跟踪数组的开始和结束位置及其当前容量。

【讨论】:

  • 我认为这种方法不适用于 set(index,element) 方法。您如何避免将整个数组从该索引向右移动?
  • set 表示改变现有元素的值。我认为您想到的需要移动的是插入。 @ShihabShahriar
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-05-13
  • 2019-01-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多