У меня было интересное интервью с собеседником некоторое время назад. Вопрос начался очень просто:
Q1: у нас есть сумка, содержащая числа
1
,2
,3
,...,100
. Каждое число появляется ровно один раз, поэтому 100 номеров. Теперь из мешка случайно выбрано одно число. Найдите недостающий номер.
Я слышал этот вопрос перед интервью, конечно, поэтому я очень быстро ответил по строкам:
A1: ну, сумма чисел
1 + 2 + 3 + … + N
равна(N+1)(N/2)
(см. Википедия: сумма арифметических рядов). ДляN = 100
сумма равна5050
.Таким образом, если все числа присутствуют в сумке, сумма будет точно
5050
. Поскольку отсутствует один номер, сумма будет меньше этого, а разница - это число. Таким образом, мы можем найти недостающее число вO(N)
время иO(1)
пробел.
В этот момент я подумал, что я преуспел, но внезапно возник вопрос:
Q2: Это правильно, но теперь, как бы вы это сделали, если отсутствовали два номера?
Я никогда раньше не видел/не слышал/не рассматривал этот вариант, поэтому я запаниковал и не мог ответить на вопрос. Интервьюер настаивал на том, чтобы узнать мой мыслительный процесс, поэтому я упомянул, что, возможно, мы сможем получить дополнительную информацию, сравнив его с ожидаемым продуктом или, возможно, сделав второй проход после сбора некоторой информации с первого прохода и т.д., Но я действительно просто снимал в темноте, а не на самом деле имеет четкий путь к решению.
Интервьюер попытался ободрить меня, сказав, что наличие второго уравнения действительно является одним из способов решения проблемы. На данный момент я был расстроен (за то, что не знал ответа раньше), и спросил, является ли это общей (программируемой) техникой программирования, или если это всего лишь трюк/ответ на вопрос.
Ответ интервьюера удивил меня: вы можете обобщить технику, чтобы найти 3 недостающих числа. Фактически, вы можете обобщить его, чтобы найти k недостающих чисел.
Qk: Если в сумме не хватает k чисел, как бы вы нашли это эффективно?
Это было несколько месяцев назад, и я до сих пор не мог понять, что это за техника. Очевидно, существует нижняя граница времени Ω(N)
, так как мы должны сканировать все числа хотя бы один раз, но интервьюер настаивал на том, что сложность решения метода TIME и SPACE (минус O(N)
время сканирования) определяется в k не N.
Итак, вопрос здесь прост:
- Как бы вы решили Q2?
- Как бы вы решили Q3?
- Как бы вы решили Qk?
Разъяснения
- Как правило, N номеров от 1..N, а не только 1..100.
- Я не ищу очевидное решение на основе набора, например. используя бит , кодируя присутствие/отсутствие каждого номера на значение назначенного бита, поэтому используя бит
O(N)
в дополнительном пространстве. Мы не можем позволить себе дополнительное пространство, пропорциональное N. - Я также не ищу очевидного метода сортировки. Этот и основанный на наборе подход заслуживают упоминания в интервью (их легко реализовать, и в зависимости от N может быть очень практичным). Я ищу решение Holy Grail (которое может быть или не быть практичным для реализации, но все же имеет желаемые асимптотические характеристики).
Итак, опять же, вы должны сканировать входные данные в O(N)
, но вы можете записывать только небольшое количество информации (определяемой в терминах k не N), и затем должны как-то найти k недостающих чисел.