Задача состоит в том, чтобы написать самую короткую реализацию, чтобы найти самую длинную возрастающую подпоследовательность .
Пример : Пусть S будет последовательность 1 5 7 1 8 4 3 5 [длина S = 8]
- У нас есть 1 подпоследовательность длины 0 [будет считать, что она увеличивается]
- 6 подпоследовательностей длиной 1 {1,5,7,8,4,3} [все они считаются возрастающими]
- (7 * 8) / 2 подпоследовательности длины 2 [но мы удалим дубликаты], увеличивающиеся подпоследовательности выделены сильным черным.
{ 15,17 , 11, 18,14,13,57 , 51, 58 , 54,53,55,71, 78 , 74,73,75,84,83,85,43, 45,35 }
[обратите внимание, что нас интересуют только строго увеличивающиеся подпоследовательности]
[вы не можете изменить порядок элементов внутри последовательности, поэтому в последовательности примеров нет подпоследовательности [37]]
- У нас есть увеличивающиеся подпоследовательности длины 4, которая равна 1578, но нет подпоследовательности длины 5, поэтому мы рассматриваем длину самой длинной увеличивающейся подпоследовательности = 4.
Вход :
a 1 a 2 ... a N (последовательность)
все числа натуральные числа меньше 10 3
N <= 1000
Выход :
Одно целое число, обозначающее длину самой длинной увеличивающейся подпоследовательности входной последовательности.
sample input(1)
1 2 4 2 5
sample output(1)
4
sample input(2)
1 5 7 1 8 4 3 5
sample output(2)
4
Ваш код должен выполняться своевременно, пожалуйста, проверьте его в этом случае, прежде чем отправлять его здесь (также ссылка содержит мое 290-байтовое решение c ++ 11)
Вы можете взять входные данные из файла / стандартного ввода или в качестве параметра функции, и вы можете либо распечатать выходные данные в файл / стандартный вывод, либо просто вернуть значение, если вы пишете функцию
Табло
- Деннис CJam - 22
- Исаакг Пиф - 26
- Говард Гольфск - 35
- гордый haskeller Haskell - 56
- Рэй Питон 3 - 66
- гистократ рубин - 67
- DLeh C # - 92
- YosemiteMark Clojure - 94
- фаубигуй питон 3 - 113
function f(){...}
) или внутренней функции (просто...
)? Если мы считаем внешние функции, разрешены ли анонимные функции?Ответы:
CJam, 22 байта
Попробуйте онлайн.
пример
Программа печатает
57
для этого теста через 0,25 секунды.Как это работает
Я взял общую идею из ответа @ Ray .
источник
Питон 3, 66
Обратите внимание, что все числа находятся в диапазоне [1, 999], мы можем использовать массив,
b
чтобы поддерживать самую длинную длину подпоследовательности, заканчивающуюся каждым числом.b[x] = d
означает, что самая длинная подпоследовательность, заканчивающаяся на,x
имеет длинуd
. Для каждого числа из входных данных мы обновляем массив с помощью,b[x] = max(b[:x]) + 1
а затем выполняем работу, взяв,max(b)
наконец.Сложность времени
На)O (mn) , гдеm
всегда 1000 иn
является количеством входных элементов.Ничего себе, похоже, уже разгулялся :) Вы можете проверить это с помощью stdin / stdout, добавив строку:
источник
for x in a: max(b)
выглядит в значительной степени O (n ^ 2).O(1000 n)
и 1000 постоянная. Вы также можете думать об этом какO(m n)
.O(1)
;-)print
короче чемreturn
.Python - 113
источник
a+=[i]*(a==[]or i>a[-1]);z=0
и печатиlen(a)
(без скобок) вы можете сохранить 4 символа.Пиф , 26
293339Порт решения @ ray. Проходит официальные испытания. Теперь используется ввод STDIN через пробел, а не вызов функции.
Запустите следующим образом:
Объяснение:
Неограниченное время:
Пиф , 18
Техническое примечание: я заметил ошибку в моем компиляторе Pyth, когда писал этот гольф.
L
не работал Вот почему есть недавний коммит в вышеупомянутый репозиторий git.источник
Clojure, 94 символа
Используя подход @ Ray для обновления результатов в векторе из 1000 элементов:
По запросу, с распечаткой заявления (напечатает ответ и вернет ноль). Входными данными должен быть вектор (g [1 2 3]) или список (g '(1 2 3)):
источник
Haskell,
585756 символовПри этом используется алгоритм, который я однажды видел в интернете, но я не могу его найти. Это занимает незаметное количество времени в данном тестовом примере на моем компьютере с GHCi (возможно, будет даже быстрее, если он будет скомпилирован).
источник
GolfScript, 35 символов
Реализация, работающая как полная программа с входом на STDIN (без указания длины). Реализация достаточно быстрая, даже для более длинных входов (попробуйте здесь ).
Примеры:
источник
$
что O (n log n), алгоритм O (n ^ 2 log n).Руби, 67
Это выполняется за 30 секунд на большом входе, это считается своевременным способом? :п
Это грубая рекурсия, но с некоторыми воспоминаниями.
источник
C #,
17292 символаНичего особенного, но я сделал это, поэтому я решил, что я мог бы также представить это.
Спасибо Армин и Боб за их улучшения!
источник
=>
не нужны. Вы также можете переместитьi=0
объявление за пределыfor
цикла, вint c=2,m=2,i=0;for(;
. Вы также можете сбросить скобки по всемуfor
телу, так как у вас есть только одно утверждение там.c++;if(c>m)m=c;
может бытьm=c++>m?m:c;
, и вы можете снова сбросить скобки вокруг этого.if(i>0)
проверки,for
начав цикл с 1. Вы можете еще больше сократитьint c=2,m=2,i=0;for(;i<j.Length;i++)if(i>0)
предложенное ранееint c=2,m=2,i=0;for(;i++<j.Length;)
. Весь этот раздел можно преобразовать вint c=2,m=2,i=0;for(;i++<j.Length;){c=j[i]>j[i-1]?c+1:2;m=c>m?m:c;}
(используя другую троицу для замены последнего оставшегосяif
- эмпирическое правило: троицы короче, если вашеif
тело - просто задание.m=c>m?m:c
должно бытьm=c>m?c:m
. И если вы добавите предложение @ Armin, вы получите 92 байта, почти вдвое меньший размер!int a(int[] j){int c=2,m=2,i=0;for(;i++<j.Length;){c=j[i]>j[i-1]?c+1:2;m=c>m?c:m;}return m;}
J , 19 байт
Попробуйте онлайн!
Запускается в O (n log n) с использованием модифицированной сортировки терпения, поскольку требуется только длина, а не фактическая подпоследовательность.
объяснение
источник
Bash + coreutils, 131 байт
Это решение ужасно не соответствует требованию своевременности и даже не является особенно коротким, но мне понравилось, что такого рода вещи, по крайней мере, теоретически возможны в сценарии оболочки, поэтому я отправляю сообщение в любом случае. Это работает с вечной сложностью времени O (2 ^ n).
Ввод - это список через запятую, передаваемый в виде одного аргумента командной строки:
Расширение скобок используется для построения списка всех возможных подпоследовательностей.
,:},{
, что создает строку вроде1,:},{5,:},{7,:},{1,:},{8,:},{4,:},{3,:},{5
{1,:},{5,:},{7,:},{1,:},{8,:},{4,:},{3,:},{5,:}
. Это допустимое расширение bash brace, которое приeval
редактировании с использованиемecho
создает этот разделенный пробелами список1,5,7,1,8,4,3,5 1,5,7,1,8,4,3,: 1,5,7,1,8,4,:,5 1,5,7,1,8,4,:,: ...
sort -C
проверяем увеличение порядка и, если да, используемwc -w
для печати длину списка.источник
Stax , 21 байт
Запустите и отладьте его
Это имеет два теста, один из которых - случай с 1000 элементами. Он запускается один раз в 24 секунды на моей машине. Он использует классический подход динамического программирования для этого типа проблемы.
источник
J 34
Обратите внимание, что я также читаю стандартный ввод.
Без чтения стандартного ввода, мясо составляет 26 символов.
Просто заметил, что мой работает медленно для большого ввода, да ладно.
источник
C ++ (gcc) , 129 байт
Попробуйте онлайн!
источник
C # (.NET Core) , 155 байт
Использовал массив для вычисления самой длинной увеличивающейся подпоследовательности, заканчивающейся в каждой позиции во входном массиве (динамическое программирование), затем возвратил наибольшее значение. Например, вычисляемый массив для ввода
[1,5,7,1,8,4,3,5]
будет иметь значение[1,2,3,1,4,2,2,3]
, и4
возвращается наибольшее значение .Попробуйте онлайн!
источник
Wolfram Language (Mathematica) , 38 байт
Попробуйте онлайн!
Конечно, есть встроенный Mathematica для поиска самых длинных упорядоченных последовательностей. Его название очень длинное: оно составляет более половины решения, и я не удивлюсь, если кто-то превзойдет это решение.
источник