Реализация очереди с использованием массива фиксированного размера - PullRequest
1 голос
/ 17 апреля 2019

Я наткнулся ниже на вопрос интервью, и я работаю над ним:

Создайте класс очереди с помощью методов enqueue и dequeue.В очереди может храниться НЕОГРАНИЧЕННОЕ количество элементов, но вы ограничены использованием массивов, которые могут хранить максимум 5 элементов.

Вот то, что я смог придуматьс.Это правильный способ сделать это на собеседовании или есть ли лучший способ, который мы должны реализовать на собеседовании?

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 голосов
/ 24 июля 2019

Обмен - Организация массивов фиксированного размера

Управление массивами на основе ArrayList

  • enqueue - добавление нового массива фиксированного размера - O (1)
  • dequeue -удалить первый массив фиксированного размера - O (n)

Управление массивами на основе LinkedList

  • enqueue - добавить новый массив фиксированного размера в связанный список - O (1)
  • dequeue - удалить первый массив фиксированного размера - O (1)
  • cons - дополнительный следующий указатель на список связанных настроек
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];
    }
}
0 голосов
/ 18 мая 2019

Как я уже упоминал в комментариях, ваше решение на самом деле не решает проблему, потому что внешний массив из 5-элементных массивов может иметь более 5 элементов.

Вместо этого вы можете реализовать очередь как связаннуюсписок 4-х целочисленных узлов, использующий 5-й элемент для ссылки на следующий массив.Но нет никаких оснований предполагать, что элементы являются целыми числами.Это оказывается довольно просто.

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++];
  }
}
0 голосов
/ 18 апреля 2019

Вы можете использовать одномерный массив и использовать циклическое индексирование для реализации очереди с ограничением, что очередь может содержать максимум 5 элементов.

Для проверки состояния пустой очереди сохраняйте переменную, котораяподсчитывает количество элементов в очереди.

0 голосов
/ 17 мая 2019

Is this the right way to do it in the interview…?
Представлять незакомментированный код никогда не бывает правильно, не говоря уже о собеседовании.
В интерактивном интервью вашей задачей было бы выяснить, можете ли вы использовать неограниченно число массив с .Если нет, вам нужно договориться о способе обработки enqueue() для очереди, заполненной до полной емкости, в дополнение к dequeue() для пустой.Исправьте тип элементов , которые может удерживать очередь.Согласуйте параметры enqueue and dequeue methods.

Задача состоит в том, чтобы Build a queue class, Solution - плохой выбор имени - array для чего-то, чтобы получить доступ к предметам, не лучше.
В языке, предоставляющем массивы, я бы взял limited to using arrays буквально - если использовать что-то большее, почему бы не реализовать java.util.Queue?
Обработка пустой очереди полностью избыточна: в enqueue() вы могли бы использовать
if (!array.isEmpty() && array.get(array.size() - 1).size() < 5)dequeue() вы можете просто уронить его.
Создание List<Integer> s, вы знаете, не будет более пяти элементов одновременно: сообщите конструктору.
dequeue()оставляет пустыми List<Integer> с в arrays, что приводит к появлению текущего вложенного цикла, который остро нуждается в комментарии.

(Для второй части вопроса я второй Раджкамаль Томар .)

0 голосов
/ 17 апреля 2019

Ваш ответ использует ArrayList вместо истинных массивов и, что еще хуже, использует неограниченный массив для добавления этих массивов. Я думаю, что интервьюеры ожидали, что вы внедрите односвязный список массивов из 5 элементов:

/**
 * 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();
    }
}

С точки зрения производительности это можно улучшить: вы можете избежать сохранения size в каждом ListNode, так как только 1-й и последний узлы могут быть не заполнены. Вы также можете избежать цикла в removeFirst, но это повлечет за собой замену size на firstIndex и lastIndex; который может быть снова перемещен в ListArrayQueue для экономии места в каждом узле.

Если бы они попросили вас создать неограниченный массив из 5-элементных массивов, вам пришлось бы реализовать нечто подобное b-tree . Который, без удобных ссылок, было бы довольно трудно осуществить во время интервью.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...