Учитывая массив целых чисел, найдите наибольшее число, используя цифры массива, чтобы оно делилось на 3
Е. Г.: Массив: 4,3,0,1,5 {считать все цифры >=0. Также каждому элементу в массиве соответствует цифра. т. е. каждый элемент массива от 0 до 9. }
в приведенном выше массиве наибольшее число: 5430 {используя цифры 5, 4, 3 и 0 из массива}
Мой Подход:
делимости на 3, нам нужна сумма цифр будет делиться на 3. Итак,
- Шаг 1: удалить все нули из массива.
- Шаг 2: Эти нули придут в конце. {Поскольку они не влияют на сумму, и мы должны найти наибольшее число}
- Шаг-3: Найдите подмножество элементов массива (исключая нули) таким образом, чтобы число цифр было максимальным, а также чтобы сумма цифр была максимальной, а сумма делилась на 3.
- Шаг-4: требуемая цифра состоит из цифр в приведенном выше наборе в порядке убывания.
Итак, основным шагом является Шаг-3, т. е. как найти подмножество так, чтобы оно содержало максимально возможное количество элементов, чтобы их сумма была максимальной и делилась на 3 .
Я думал, может быть, Шаг-3 может быть сделан жадным выбором взять все элементы и продолжать удалять наименьший элемент в наборе, пока сумма не будет делиться на 3.
но я не уверен, что этот жадный выбор сработает.
пожалуйста, скажите, если мой подход правильный. Если это так, то, пожалуйста, предложите, как сделать Шаг-3 ?
кроме того, пожалуйста, предложите любой другой возможный/эффективный алгоритм.
6 ответов
наблюдения: если вы можете получить число, кратное 3, вам нужно удалить не более 2 чисел, чтобы поддерживать оптимальное решение.
простой O(n^2)
решение будет проверять все возможности для удаления 1 числа, и если ни один из них не действителен, проверьте все пары (есть O(n^2)
те).
EDIT:
O(n)
решение: создайте 3 ведра -bucket1
, bucket2
, bucket0
. Каждый будет обозначать значение модуля 3 число. Игнорировать bucket0
в следующем алгоритме.
пусть сумма массива будет sum
.
If sum % 3 ==0: we are done.
else if sum % 3 == 1:
if there is a number in bucket1 - chose the minimal
else: take 2 minimals from bucket 2
else if sum % 3 == 2
if there is a number in bucket2 - chose the minimal
else: take 2 minimals from bucket1
Примечание: На самом деле вам не нужно ведро, чтобы достичь O(1)
space-вам нужно только 2 минимальных значения из bucket1
и bucket2
, так как это единственное число, которое мы использовали с этими ведрами.
пример:
arr = { 3, 4, 0, 1, 5 }
bucket0 = {3,0} ; bucket1 = {4,1} bucket2 = { 5 }
sum = 13 ; sum %3 = 1
bucket1 is not empty - chose minimal from it (1), and remove it from the array.
result array = { 3, 4, 0, 5 }
proceed to STEP 4 "as planned"
жадный выбор определенно не работает: рассмотрим набор {5, 2, 1}
. Вы бы удалили 1
во-первых, но вы должны удалить 2
.
Я думаю, вы должны вычислить сумму массива по модулю 3, которая равна либо 0 (вы закончили), либо 1, либо 2. Затем вы хотите удалить минимальное подмножество, сумма которого по модулю 3 равна 1 или 2.
Я думаю, что это довольно просто, поэтому нет реальной необходимости в динамическом программировании. Сделайте это, удалив одно число с этим модулем, если возможно, в противном случае сделайте это, удалив два числа с другим модулем. После того, как вы знаете, сколько удалить, выберите наименьшее возможное. Вам никогда не придется удалять три номера.
вам не нужно лечить 0
специально, хотя если вы собираетесь это сделать, то вы можете дополнительно уменьшить набор, рассматриваемый на Шаге 3, Если вы временно удалите все 0, 3, 6, 9 из него.
сложив все это вместе, я бы, наверное:
- сортировка цифр, нисходящий.
- вычислить модуль. Если 0, мы закончили.
- Попробуйте удалить цифру с этим модулем, начиная с конца. Если все получится, нам конец.
- удалите две цифры с отрицательным модулем, начиная с конца. Это всегда удается, так что мы закончили.
- мы можем остаться с пустым массивом (например, если вход
1, 1
), в этом случае проблема была невозможна. В противном случае массив содержит цифры результат.
сложность времени O(n)
при условии, что вы делаете сортировку подсчета на шаге 1. Что вы, конечно, можете, так как значения цифр.
что вы думаете об этом:
сначала отсортируйте элементы массива по значению
sum up all numbers
- if sum's remainder after division by 3 is equal to 0, just return the sorted
array
- otherwise
- if sum of remainders after division by 3 of all the numbers is smaller
than the remainder of their sum, there is no solution
- otherwise
- if it's equal to 1, try to return the smallest number with remainder
equal to 1, or if no such, try two smallest with remainder equal to 2,
if no such two (I suppose it can happen), there's no solution
- if it's equal to 2, try to return the smallest number with remainder
equal to 2, or if no such, try two smallest with remainder equal to 1,
if no such two, there's no solution
сначала отсортируйте элементы массива по остатку деления на 3 по возрастанию затем каждое подмножество равного остатка сортируется по значению по убыванию
во-первых, эта задача сводится к максимизации количества элементов выбрана такой, что их сумма делится на 3.
Trivial: выберите все числа, кратные 3 (0,3,6,9).
Le A-элементы, которые оставляют 1 как остаток, b-элементы, которые оставляют 2 как остаток. Если (|a|-|b/)%3 равно 0, выберите все элементы из a и b. Если (|a|-|b|)%3 равно 1, Выберите все элементы из b и|a / -1 наибольшее число из a. Если остаток равен 2, Выберите все числа из a и|b / -1 наибольшее число из b.
Если у вас есть все цифры, отсортировать их в обратном порядке и сцепления. это твой ответ.
в конечном счете, если n-количество элементов, этот алгоритм возвращает число, которое имеет длину не менее n-1 цифр (за исключением угловых случаев. смотреть ниже.)
Примечание: позаботьтесь о угловых случаях (т. е. Что такое |a|=0 или |b|=0 и т. д.). (-1)%3 = 2 и (-2)%3 = 1 .
Если m-размер алфавита, а n-число элементы, это мой алгоритм O (m+n)
сортировка данных не требуется, так как существует только десять различных значений. Просто подсчитайте количество нулей, единиц, двоек и т. д. в O (n), если задано n цифр. Вычислите сумму всех цифр, проверьте, равен ли остаток по модулю 3 0, 1 или 2.
Если остаток равен 1: снять первую из следующих что возможно (один из них гарантированно будет возможно): 1, 4, 7, 2+2, 2+5, 5+5, 2+8, 5+8, 8+8.
Если остаток равен 2: Удалите первый из после чего возможно (один из них гарантированно будет возможно): 2, 5, 8, 1+1, 1+4, 4+4, 1+7, 4+7, 7+7.
Если там нет цифр, то проблема не может быть решена. В противном случае решение создается путем объединения 9, 8, 7 и так далее столько, сколько осталось.
(сортировка N цифр займет O (N log n). Если, конечно, вы не сортируете, подсчитывая, как часто происходит каждая цифра и генерируя отсортированный результат в соответствии с этими числами).
в ответе Амита отсутствует крошечная вещь.
Если bucket1 не пуст, но имеет огромное значение, скажем, 79 и 97, А b2 не пуст, а его 2 минимала, скажем, 2 и 5. Тогда в этом случае, когда модуль суммы всех цифр равен 1, мы должны выбрать удаление 2 и 5 из ведра 2 вместо минимального в ведре 1, чтобы получить наибольшее сцепленное число.
тест : 8 2 3 5 78 79
Если мы будем следовать Amits и Стива предложил способ, наибольшее количество будет 878532, тогда как наибольшее количество возможных divisble по 3 в этом массиве 879783
решением было бы сравнить наименьший минимум соответствующего ведра с конкатенацией обоих минималов другого ведра и исключить меньший.