가장 짧은 가장 긴 증가하는 서브 시퀀스 코드


11

문제는 가장 긴 하위 시퀀스 를 찾기 위해 가장 짧은 구현 을 작성하는 것 입니다.

: S를 시퀀스 1 5 7 1 8 4 3 5로 설정합니다 [S의 길이 = 8]

  • 길이가 0 인 하위 시퀀스가 ​​1 개 있습니다.
  • 길이가 1 {1,5,7,8,4,3} 인 6 개의 하위 시퀀스 [모두 증가하는 것으로 간주 됨]
  • 길이 7의 (7 * 8) / 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 솔루션이 포함되어 있습니다)

파일 / stdin 또는 함수 매개 변수에서 입력을 가져 와서 출력을 파일 / stdout으로 인쇄하거나 함수를 작성하는 경우 값을 리턴 할 수 있습니다

스코어 보드

  1. 데니스 CJam- 22
  2. isaacg Pyth- 26
  3. 하워드 골프 스크립트 -35
  4. 자랑스런 하스 켈러 하스켈 -56
  5. 레이 파이썬 3-66
  6. histocrat 루비 - 67
  7. DLeh C # -92
  8. 요세미티 마크 클로저 -94
  9. faubiguy 파이썬 3 - (113)

1
"길이 0의 하위 시퀀스가 ​​1 개 있습니다. [증가하는 것으로 간주합니다]"기술적으로 무한 길이의 0 길이 하위 시퀀스가 ​​있습니다. :)
Cruncher

실제로, 모든 "Sets"가 중복을 제거하도록 문장을 변경해야합니다. 예를 들어 {1,5,7,1,8,4,3,5}는 {1,5,7,8,4 여야합니다. , 3} 그리고 "Set"에 1 0 길이의 서브 시퀀스가 ​​있다고 말할 수 있습니다. 감사
Mostafa 36a2

1
함수의 경우 외부 함수 ( function f(){...}) 또는 내부 함수 (그냥 ...) 의 바이트 수를 계산해야 합니까? 외부 함수를 세면 익명 함수가 허용됩니까?
Dennis

외부 함수를 세고 익명 함수는 허용되지만 테스트 가능한 버전 (입력 / 출력 처리 기능이있는 완전한 버전)을 제공하는 것을 놓치지 마십시오
Mostafa 36a2

답변:


2

CJam, 22 바이트

1e3,q~{_2$<$0=(t}/$0=z

온라인으로 사용해보십시오.

$ cjam subsequence.cjam <<< '[2 1]'; echo
1
$ cjam subsequence.cjam <<< '[1 9 2 4 3 5]'; echo
4

프로그램은 0.25 초 후에이 테스트 케이스를 인쇄 57합니다 .

작동 원리

@Ray의 답변 에서 일반적인 아이디어를 얻었습니다 .

1e3,    " Push the array [ 0 ... 999 ] (J).        ";
q~      " Read from STDIN and evaluate.            ";
{       " For each integer (I) of the input array: ";
  _2$<  " Push [ J[0] ... J[I - 1] ] (A).          ";
  $0=(  " Compute min(A) - 1.                      ";
  t     " Update J[I] with the value on the stack. ";
}/      "                                          ";
$0=     " Compute abs(min(J)).                     ";

5

파이썬 3, 66

모든 숫자의 범위는 [1, 999]이며 배열 b을 사용하여 각 숫자로 끝나는 가장 긴 하위 시퀀스 길이를 유지할 수 있습니다. b[x] = d로 끝나는 가장 긴 하위 시퀀스의 x길이가 임을 의미합니다 d. 입력의 각 숫자에 대해를 사용하여 배열을 업데이트 b[x] = max(b[:x]) + 1한 다음 max(b)마지막으로 작업을 완료했습니다 .

시간의 복잡성은 의 위에) O (mn) , 여기서 m항상 1000이며 n입력 요소 수입니다.

def f(a):
 b=[0]*1000
 for x in a:b[x]=max(b[:x])+1
 return max(b)

와우, 이미 ungolfed 것 같습니다 :) stdin / stdout을 사용하여 테스트 할 수 있습니다.

print(f(map(int,input().split())))

for x in a: max(b)거의 O (n ^ 2)로 보입니다.
Howard

@Howard 그것은 O(1000 n)1000은 상수입니다. 당신은 또한 그것을 생각할 수 있습니다 O(m n).
Ray

3
제한된 입력에 복잡성이 항상 있기 때문에 이러한 인수가 전체 논의는 쓸모가 O(1);-)
하워드

@Howard 나는 ACM-ICPC 세계에서 왔으며 이것은 다소 컨벤션입니다. O (mn)로 생각할 수 있습니다. 여전히 O (n ^ 2)와 다릅니다. 어쨌든, 비용은 통역사 시작 시간보다 짧을 것이므로 충분히 빠르다고 생각합니다.
Ray

매우 짧은 알고리즘! 하나의 문자 만 찾을 수 있습니다 (적어도 Python 2로 전환 할 때) : 결과를 인쇄 할 수 있습니다. print보다 짧습니다 return.
Falko

3

파이썬-113

a=[]
for i in map(int,input().split()):
 if not a or i>a[-1]:a+=[i]
 z=0
 while a[z]<i:z+=1
 a[z]=i
print(len(a))

수용된 해결책. 귀하의 코드는 여기여기 에서 테스트되었습니다 .
Mostafa 36a2

@ Mostafa36a2 "accepted"라는 단어는이 사이트에서 다른 의미를 갖습니다. 나는 당신이 의미하는 것이 "허용 가능"하다고 생각합니다.
Ray

죄송합니다. 예, 수락 할 수있는 것을 선택하기에 너무 일찍 허용했습니다.
Mostafa 36a2

a+=[i]*(a==[]or i>a[-1]);z=0과 인쇄 len(a)(괄호없이)를 사용하면 4자를 저장할 수 있습니다.
Falko

3

피스 , 26 29 33 39

J*]0^T3Fkyw=@JkheS:J0k)eSJ

@ray 솔루션의 포트. 공식 테스트를 통과합니다. 이제 함수 호출이 아닌 공백으로 구분 된 STDIN 입력을 사용합니다.

다음과 같이 실행하십시오.

./pyth.py -c "J*]0^T3Fkyw=@JkheS:J0k)eSJ" <<< "1 5 7 2 8 4 3 5"
4

설명:

J*]0^T3                 J = [0]*10^3
Fkyw                    For k in space_sep(input()):
=@Jk                    J[k]=
heS:J0k                 max(J[0:k])+1
)                       end for
eSJ                     max(J)

무제한 시간 :

피 이스 , 18

L?eS,ytbhyf>Thbbb0

기술 노트 :이 골프를 쓰는 동안 Pyth 컴파일러에서 버그가 발견되었습니다. L작동하지 않았다. 그래서 위의 git 저장소에 최근 커밋이있는 이유입니다.


코드가 큰 목록 (100 개 요소)을 가진 경우에는 적시에 코드가 실행되지 않습니다.
Mostafa 36a2

3
@ Mostafa36a2 런타임을 요구 사항으로 만들고 싶다면 질문에서 말하고 테스트 사례를 추가하십시오. 그것이 단지 의견이라면, 나는 매우 느리다는 것에 동의합니다.
isaacg

죄송하지만 코드가 10-20 분 또는 1 시간이 걸리더라도 문제가되지 않지만 런타임은 아니지만 최소한 [적시 방식]이라고 언급했지만 O (2 ^ n) 솔루션은 결과가 나오지 않습니다. 우리의 장수.
Mostafa 36a2

@ Mostafa36a2 알았습니다. 방금 그 줄을 알았습니다. 개선을 위해 노력하겠습니다.
isaacg

1
죄송합니다. 지금 업데이트가 표시됩니다. 이 사례 를 사용해보고 작동하는지 알려주세요.
Mostafa 36a2

3

클로저, 94 자

결과를 업데이트하는 @Ray의 접근 방식을 사용하면 1000 개 항목 벡터가 생성됩니다.

(defn g[s](apply max(reduce #(assoc % %2(inc(apply max(take %2 %))))(into[](repeat 1e3 0))s)))

인쇄 문과 함께 요청마다 (응답을 인쇄하고 nil을 반환합니다). 입력은 벡터 (g [1 2 3]) 또는 목록 (g '(1 2 3))이어야합니다.

(defn g[s](prn(apply max(reduce #(assoc % %2(inc(apply max(take %2 %))))(into[](repeat 1e3 0))s))))

print 문을 추가하여 테스트 할 수 있습니까? 점수에는 포함되지 않습니다.
Mostafa 36a2

1
업데이트되었습니다. 나는 당신의 큰 예제 모두에서 그것을 실행했으며 예상대로 58과 57을 얻었습니다.
YosemiteMark

나는 여전히 함수 : p를 호출해야한다고 생각하지만 테스트했다면 충분하다.
Mostafa 36a2

3

하스켈, 58 57 56 자

(x:s)%v|v>x=x:s%v|0<1=v:s
_%v=[v]
l s=length$foldl(%)[]s

이것은 인터넷에서 한 번 본 알고리즘을 사용하지만 찾을 수 없습니다. GHCi를 사용하는 컴퓨터에서 주어진 테스트 케이스에서 눈에 띄지 않는 시간이 걸립니다 (아마도 컴파일 된 경우 더 빠를 것입니다).


언급 한 알고리즘은 @faubiguy에서 사용한 것과 동일합니다.
Ray

@ 레이 당신이 맞아
자랑스런 Haskeller

2

GolfScript, 35 자

~]]){1${~2$<*)}%1+$-1>[\+]+}/$-1=0=

STDIN에 입력 된 길이가없는 완전한 프로그램으로 작동하는 구현. 더 긴 입력에 대해서도 구현이 합리적이고 빠릅니다 ( 여기 시도 ).

예 :

> 1 5 7 1 8 4 3 5
4

> 5 1 9 9 1 5
2

1
@ MartinBüttner 컴퓨터에서 1000 개의 숫자를받는 데 약 5 초가 걸립니다. $O (n log n) 라고 가정하면 알고리즘은 O (n ^ 2 log n)입니다.
Howard


@ Mostafa36a2 나는 이미했다 (이전 주석 참조). 5 초 후 58을 반환합니다.
Howard

이 코드는 다음 반환 57 그것의 허용 :) 축하 한 경우에 그렇게, 57을 반환해야합니다, 또 다른 하나입니다
모스 타파 36a2

@ Mostafa36a2 아, 이제 두 가지 테스트 사례가 있습니다. 예, 두 번째 링크는이 입력에 대한 솔루션과 마찬가지로 57을 반환합니다.
Howard

2

루비, 67

s=Hash.new{|s,a|f,*r=a
s[a]=f ?[1+s[r.select{|x|x>f}],s[r]].max: 0}

이것은 큰 입력에서 30 초 안에 실행되며 적시에 계산됩니까? :피

잔인한 재귀이지만 약간의 메모가 있습니다.


1
예,이 적시는 :)입니다
모스 타파 36a2

2

C #, 172 92 자

특별한 것은 없었지만 제출했지만 제출할 수도 있다고 생각했습니다.

int a(int[] j){int c=2,m=2,i=1;for(;++i<j.Length;){c=j[i]>j[i-1]?c+1:2;m=c>m?c:m;}return m;}

개선 사항에 대해 Armin과 Bob에게 감사드립니다!


1
매개 변수를 int []로 변경할 수 있고 문자열을 int로 캐스트 할 필요가 없기 때문에 문자 수가 줄어 듭니다.
Armin

2
주변 공간 =>은 불필요합니다. 루프 i=0외부로 선언 을으로 이동할 수도 있습니다 . 거기에 하나의 문장 만 있기 때문에 몸통에 버팀대를 놓을 수도 있습니다. forint c=2,m=2,i=0;for(;for
Bob

그리고 c++;if(c>m)m=c;가 될 수 있으며 m=c++>m?m:c;, 그 주위에 괄호를 다시 떨어 뜨릴 수 있습니다.
Bob

1
사실, 당신은 또한 버릴 수 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;}(마지막 남은 부분을 대체하기 위해 다른 삼항을 사용 ifif몸이 단순히 과제 인 경우 엄지 손가락의 규칙은 삼항이 짧습니다 .
Bob

2
내 이전 의견에 오타 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;}
Bob

2

J , 19 바이트

[:#]`I.`[} ::,~/@|.

온라인으로 사용해보십시오!

실제 하위 시퀀스가 ​​아닌 길이 만 필요하므로 수정 된 인내심 정렬을 사용하여 O (n log n) 에서 실행됩니다 .

설명

[:#]`I.`[} ::,~/@|.  Input: array
                 |.  Reverse
               /     Reduce right-to-left
     I.                Find the index to insert while keeping it sorted
                       (uses binary search)
         }             Amend the current search array at that index with the next value
           ::          If error (when the index is not found)
             ,           Append the value at the end
 #                   Length of that array

1

Bash + coreutils, 131 바이트

이 솔루션은 적시에 요구 사항 에 대해 끔찍하게 실패 하며 특히 짧지는 않지만 쉘 스크립트에서는 이론적으로 가능하다는 것을 좋아했기 때문에 어쨌든 게시하고 있습니다. 이것은 영원을 유발하는 시간 복잡성 O (2 ^ n)로 실행됩니다.

s=${1//,/,:\},\{}
a=`eval echo "{$s,:}"`
for s in $a;{
b="$(tr , \\n<<<$s|grep -v :)"
sort -nC<<<"$b"&&wc -w<<<$b
}|sort -nr|sed 1q

입력은 단일 명령 행 인수로 전달 된 쉼표로 구분 된 목록입니다.

$ time ./slisc.sh 1,5,7,1,8,4,3,5
4

real    0m1.240s
user    0m0.518s
sys 0m0.689s
$ 

중괄호 확장은 가능한 모든 하위 시퀀스 목록을 작성하는 데 사용됩니다.

  • 첫 번째 줄은 쉼표를로 바꾸어 다음과 ,:},{같은 문자열을 생성합니다.1,:},{5,:},{7,:},{1,:},{8,:},{4,:},{3,:},{5
  • 두 번째 줄은이 문자열을 중괄호, 쉼표 및 세미콜론으로 완성하여 이것을 제공합니다 {1,:},{5,:},{7,:},{1,:},{8,:},{4,:},{3,:},{5,:}. 이것은 유효한 bash 괄호 확장으로, evaled와 함께 사용할 때 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,:,: ...
  • 기본적으로 bash는 문자열을 공백으로 분할 하므로이 목록의 각 요소를 반복합니다.
    • 쉼표는 개행 문자로 대체 된 다음 콜론을 포함하는 행이 제거되어 가능한 각 하위 시퀀스에 대해 개행 문자로 구분 된 목록을 제공합니다.
    • 그런 다음 sort -C증가하는 순서를 테스트하고, 그렇다면 wc -w목록의 길이를 인쇄하는 데 사용 하십시오
  • 결과로 생성 된 목록 길이 목록은 역순으로 정렬되며 첫 번째 값이 인쇄되어 가장 긴 하위 시퀀스 길이를 제공합니다.

1

Stax , 21 바이트

ë/NS7Γ╥╚┌{1╤╒¬è¶²╢╦┌☼

실행 및 디버깅

여기에는 두 가지 테스트 사례가 있으며 그 중 하나는 1000 요소 사례입니다. 내 컴퓨터에서 24 초 안에 그 중 하나를 실행합니다. 이 유형의 문제에 대해 고전적인 동적 프로그래밍 방식을 사용합니다.


0

J 34

표준 입력도 읽습니다.

>./;+/@:*&.>(<*>.)/\&.><\.".1!:1]3

표준 입력을 읽지 않으면 고기는 26 자입니다.

>./;+/@:*&.>(<*>.)/\&.><\.

방금 큰 입력으로 인해 광산이 느리게 작동하는 것을 알았습니다.



0

C # (. NET 코어) 155 바이트

배열을 사용하여 입력 배열의 각 위치에서 끝나는 가장 긴 하위 시퀀스를 계산 한 다음 (동적 프로그래밍) 가장 큰 값을 반환했습니다. 예를 들어, 입력에 대한 계산 된 어레이는 [1,5,7,1,8,4,3,5][1,2,3,1,4,2,2,3], 및 최대 값을 4반환한다.

int b(int[]x){int l=x.Length,r=1,i=0,j,c;var a=new int[l];a[0]=1;while(++i<l)for(j=0;j<i;j++){c=x[j]<x[i]?a[j]+1:1;a[i]=a[i]<c?c:a[i];r=r<c?c:r;}return r;}

온라인으로 사용해보십시오!


당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.