Programmers :: 스타 수열

숑숑·2021년 5월 6일
0

알고리즘

목록 보기
84/122
post-thumbnail

문제

다음과 같은 것들을 정의합니다.

  • 어떤 수열 x의 부분 수열(Subsequence)이란, x의 몇몇 원소들을 제거하거나 그러지 않고 남은 원소들이 원래 순서를 유지하여 얻을 수 있는 새로운 수열을 말합니다.

  • 예를 들어, [1,3]은 [1,2,3,4,5]의 부분수열입니다. 원래 수열에서 2, 4, 5를 제거해서 얻을 수 있기 때문입니다.

다음과 같은 조건을 모두 만족하는 수열 x를 스타 수열이라고 정의합니다.

  • x의 길이가 2 이상의 짝수입니다. (빈 수열은 허용되지 않습니다.)
  • x의 길이를 2n이라 할 때, 다음과 같은 n개의 집합 {x[0], x[1]}, {x[2], x[3]}, ..., {x[2n-2], x[2n-1]} 의 교집합의 원소의 개수가 1 이상입니다.
  • x[0] != x[1], x[2] != x[3], ..., x[2n-2] != x[2n-1] 입니다.
  • 예를 들어, [1,2,1,3,4,1,1,3]은 스타 수열입니다. {1,2}, {1,3}, {4,1}, {1,3} 의 교집합은 {1} 이고, 각 집합 내의 숫자들이 서로 다르기 때문입니다.

1차원 정수 배열 a가 매개변수로 주어집니다. a의 모든 부분 수열 중에서 가장 길이가 긴 스타 수열의 길이를 return 하도록 solution 함수를 완성해주세요. 이때, a의 모든 부분 수열 중에서 스타 수열이 없다면, 0을 return 해주세요.


🤔 생각

  • 꽤 복잡해보인다. DP나 DFS 같은 전수조사 알고리즘을 써야하나..

  • 딱히 적절한 솔루션이 없는거 같아서 그냥 생각나는대로 구현했다.

  • 스타수열을 가장 빠르게 찾는 방법은, 빈도수가 가장 높은 수부터 검사하는 것이다. (교집합이 되어야 하므로 빈도가 높음)

  • 그 다음 교집합 조건, 서로 다른 수 조건을 체크해 스타수열 여부를 가린다. 맞다면 수열의 길이를 저장한다.

  • 위 과정을 모든 수에 반복하고 최댓값을 반환한다.

📌 내 풀이

from collections import Counter

def solution(a):
    answer = -1
    
    cnt = Counter(a)
    for k,v in cnt.most_common():
        if cnt[k]*2 <= answer: continue
        
        idx = 0
        maxv = k
        length = 0
        
        while idx < len(a) - 1:
            if (a[idx] != maxv and a[idx+1] != maxv) or a[idx] == a[idx+1]:
                idx += 1
                continue
            
            length += 2
            idx += 2
        
        answer = max(answer, length)
    
    return answer
profile
툴 만들기 좋아하는 삽질 전문(...) 주니어 백엔드 개발자입니다.

0개의 댓글