Implement Queue using fixed size array

时间:2019-04-17 00:01:51

标签: java algorithm data-structures

I came across below interview question and I am working on it:

Build a queue class with the enqueue and dequeue methods. The queue can store an UNLIMITED number of elements but you are limited to using arrays that can store up to 5 elements max..

Here is what I was able to come up with. Is this the right way to do it in the interview or is there any better way we should implement in the interview?

class Solution {  
  private final List<List<Integer>> array;

  public Solution() {
    this.array = new ArrayList<>();
  }

  public void enqueue(int value) {
    if(array.isEmpty()) {
      List<Integer> arr = new ArrayList<>();
      arr.add(value);
      array.add(arr);
      return;
    }
    if(array.get(array.size() - 1).size() != 5) {
      array.get(array.size() - 1).add(value);   
      return;
    }
    List<Integer> arr = new ArrayList<>();
    arr.add(value);
    array.add(arr);
    return;
  }

  public int dequeue() {
    if(array.isEmpty()) {
      return -1; 
    }
    for(List<Integer> l : array) {
      for(int i=0; i<l.size(); i++) {
        return l.remove(i); 
      }
    }
    return -1;
  }
}

5 个答案:

答案 0 :(得分:0)

Your answer uses ArrayList instead of true arrays, and worse, uses an unlimited arraylist to put those arrays in. I think that the interviewers expected you to implement a singly-linked list of 5-element arrays:

/**
 * A singly-linked list node with an array; supports popping its 1st elements, 
 * and adding elements at the end, possibly by creating a new node
 */
public class ListNode {
    final int MAX = 5;
    private int contents[] = new int[MAX];
    private int size = 0; // valid elements

    private ListNode next = null;
    private ListNode(ListNode next) {
        this.next = next;
    }

    public boolean isEmpty() { return size == 0; }

    public ListNode addLast(int value) {
        ListNode next = this;
        if (size == MAX) {
            next = new ListNode(this);
        }
        next.contents[next.size ++] = value;
        return next;
    }

    public int removeFirst() {
        if (size == 0) {
            throw new NoSuchElementException("empty queue");
        }
        int value = contents[0];
        size --;
        for (int i=1; i<size; i++) contents[i-1] = contents[i];
        return value;
    }
}

/**
 * A simple queue on top of nodes that keep arrays of elements
 */
public class ListArrayQueue {
    ListNode first = new ListNode();
    ListNode last = first;
    public void enqueue(int value) {
        last = last.addLast(value);
    }
    public int dequeue() {
        if (first.isEmpty() && first != last) {
            first = first.next;
        }
        return first.removeFirst();
    }
}

Performance-wise, this can be improved: you can avoid keeping the size in each ListNode, since only the 1st and last nodes can be non-full. You can also avoid the loop in removeFirst, but that would entail replacing size by firstIndex and lastIndex; which could again be moved into the ListArrayQueue to save space in each node.

If they has asked you to build an unlimited array out of 5-element array pieces, you would have had to implement something similar to a b-tree. Which, without handy references, would be quite hard to pull off during an interview.

答案 1 :(得分:0)

您可以使用一维数组并使用环绕索引来实现队列,但要限制队列最多可以包含5个元素。

要检查空队列的状况,请维护一个变量,该变量对队列中存在的元素数进行计数。

答案 2 :(得分:0)

Is this the right way to do it in the interview…?
呈现未注释的代码永远是不正确的,更不用说在采访中了。
在交互式采访中,查找是否可以/应该使用无限数量的数组 s 是您的任务。 如果不是这样,除了enqueue()空的队列之外,您还必须协商一种方法来处理dequeue()到已满的队列。 修复队列可以容纳的 items 的类型。 同意enqueue and dequeue methods的参数。

任务是Build a queue classSolution是名称的错误选择-array不能访问某些东西。
在提供数组的语言中,我会按字面意义理解limited to using arrays-如果要使用更多的东西,为什么不实现java.util.Queue
空队列处理完全多余:在enqueue()中,您可能已经使用过
if (!array.isEmpty() && array.get(array.size() - 1).size() < 5);在dequeue()中,您可以将其删除。
实例化List<Integer>您知道一次最多只能有五个项目:告诉构造函数。
dequeue()List<Integer>中留空arrays,导致当前嵌套循环迫切需要注释。

(对于问题的第二部分,我第二次Rajkamal Tomar。)

答案 3 :(得分:0)

正如我在评论中提到的那样,您的解决方案并不能真正解决问题,因为5元素数组的外部数组可以包含5个以上的元素。

相反,您可以使用第5个元素作为对下一个数组的引用,将队列实现为4个整数节点的链接列表。但是没有理由假设元素是整数。事实证明这很简单。

public class SillyQueue<T> {
  private static final int MAX = 5;
  private Object [] head = new Object[MAX], tail = head;
  private int headPtr = 0, tailPtr = 0;

  void enqueue(T x) {
    if (tailPtr == MAX - 1) {
      Object [] a = new Object[MAX];
      tail[MAX - 1] = a;
      tail = a;
      tailPtr = 0;
    }
    tail[tailPtr++] = x;
  }

  T dequeue() {
    if (headPtr == MAX - 1) {
      head = (Object[]) head[MAX - 1];
      headPtr = 0;
    }
    return (T) head[headPtr++];
  }
}

答案 4 :(得分:0)

权衡取舍-组织固定大小的数组

基于ArrayList管理阵列

  • 排队-追加新的固定大小的数组-O(1)
  • 出队-删除第一个固定大小的数组-O(n)

基于LinkedList管理数组

  • 排队-将新的固定大小的数组附加到链表-O(1)
  • 出队-删除第一个固定大小的数组-O(1)
  • 缺点-指向设置链接列表的下一个指针
public class FixedArrayQueue<T> {
    private Node<T> head, tail;
    private int front, rear, size;
    private final int SIZE;

    public FixedArrayQueue(int n) {
        SIZE = n;
        head = tail = new Node<T>(SIZE);
        front = rear = size = 0;
    }

    public void enqueue(T t) {
        tail.array[rear++] = t;
        if (rear == SIZE) {
            rear = 0;
            append();
        }
        size++;
    }

    public T dequeue() {
        if (size == 0) {
            throw new EmptyQueueException();
        }
        T ret = head.array[front++];
        if (front == SIZE) {
            front = 0;
            remove();
        }

        size--;
        return ret;
    }

    private void append() {
        tail.next = new Node<T>(SIZE);
        tail = tail.next;
    }

    private void remove() {
        head = head.next;
    }

    private boolean isEmpty() {
        return size == 0;
    }

    private int size() {
        return size;
    }
}

class Node<T> {
    T[] array;
    Node<T> next;

    public Node(int n) {
        array = (T[]) new Object[n];
    }
}