как найти хорошее решение или оптимизировать решение

#java #data-structures

#java #структуры данных

Вопрос:

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

Вопрос: Допустим, у нас есть поток целых чисел (очень большой список). Что-то вроде: 1, 2, 7, 3, 9, 4, 1, 2, 5, …, -1. Последний элемент в потоке всегда равен ‘ -1’. функция int read() возвращает следующий элемент из потока, и другого способа чтения из этого потока нет.

  • Напишите метод, int[] last5(), который возвращает последние 5 элементов из потока.
  • Напишите метод, int[] last5unique(), который возвращает последние 5 уникальных элементов, отсортированных по последнему появлению (позиции) в потоке. Например, stream: 1 2 3 2 4 5 последними 5, отсортированными по вхождению, являются: 1 3 2 4 5. Обратите внимание, что позиция последних 2 больше, чем позиция последних 3.

и я придумал следующее

 public int[] last5() {

  int[] toReturn = new int[5];

  int last = read(); 
  int counter = 0; 
  toReturn[counter] = last; 
  counter  ; 

  while (last != -1) {
    last = read(); 
    toReturn[counter] = last; 
    counter  ; 

    if (counter == 5) {
      counter = 0 
    }
  }
  return toReturn;
}


public int[] last5unique() {

  int[] toReturn = new int[5];
  Vector<Integer> tmp = new Vector<Integer>();

  int last = read(); 
  tmp.add(last); 

  while (last != -1) {
    last = read(); 
    if (!tmp.contains(last)) {
      tmp.add(last); 
    }
    else {
      for (int i=0; i<tmp.size(); i  ) {
        if (tmp.get(i) == last) {
          tmp.remove(i); 
          break;
        }
      }
      tmp.add(last); 
    }
    if (tmp.size() == 5 amp;amp; last != -1) {
      tmp.remove(0); 
    }
  }

  for (int i=0; i<tmp.size(); i  )
    toReturn[i] = tmp.get(i);

  return toReturn;
}
  

Комментарии:

1. Следует ли возвращать значение -1? В настоящее время ваши методы возвращают его. Имеет ли значение позиция в int[] last5() ? Т.Е. если последние 5 чисел {5, 6, 8, 9, 15}, нормально ли возвращать {15, 6, 8, 9, 5}?

2. Интервьюер сказал, что можно возвращать значение -1, а для метода last5() порядок не имеет значения.

Ответ №1:

Ваша функция last5() неверна, потому что, если у вас есть 6 чисел (или любое количество, не кратное 5) после того, как вы прочитаете 5 чисел, вы снова начнете писать с позиции [0] из-за

 if (counter == 5) {
  counter = 0 
}
  

и я думаю, что это не то, что они требуют, чтобы функция выполняла.
Если ваш поток 0, 1, 2, 3, 4, 5, 6, 7, -1 ваша функция вернет 5, 6, 7, 3, 4 но, на мой взгляд, оно должно возвращать 3, 4, 5, 6, 7

Мое решение для last5 () было бы чем-то вроде:

 public int[] last5() {
        LinkedList<Integer> list = new LinkedList<>();
        int[] toReturn = new int[5];
        int quantity = 0;
        int last;

        last = read();
        while (last != -1) {
            list.add(last);

            if (quantity >= 5)
                list.pop();
            else
                quantity  ;
            last = read();
        }

        for (int i = 0; i < quantity; i  ) {
            toReturn[i] = list.get(i);
        }
        return toReturn;
    }
}
  

Я использовал LinkedList для сохранения структуры данных очереди, содержащей всего 5 элементов (или меньше). Вы также можете избежать LinkedList, но вам нужен дополнительный цикл while / for, чтобы переместить в предыдущую позицию все элементы после того, как вы прочитали 5 элементов.
Таким образом, вы можете сохранить исходное положение элементов из потока.