우선 문제에서 "{x[0], x[1]}, {x[2], x[3]}, ..., {x[2n-2], x[2n-1]} 의 교집합의 원소의 개수가 1 이상입니다." 라고 하는 것이 있는데, 교집합의 원소의 개수가 2개가 되면 "x[0] != x[1], x[2] != x[3], ..., x[2n-2] != x[2n-1]"에 위배되기 때문에 1개 입니다.
즉 이 문제는 고정된 원소 a가 있고, 이에 대응되는 원소 b가 존재만 하면 됩니다.
예를 들어서 [0, 3, 0, 3, 0, 3, 0, 3] 이라고 하는 배열에 0을 a에 집어넣어 봅시다.
각 0들을 a1, a2, a3, a4라고 하면, "각각에 a1, a2, a3, a4 옆에(왼쪽 혹은 오른쪽) 원소가 존재 하는가?"를 판별만 하면 됩니다.
이 경우에는 다음과 같습니다.
[a1, 3, a2, 3, a3, 3, a4, 3]
즉 [ak, r]에 해당하는 원소 쌍이 4개 가능하고, 이 4개는 모두 스타 배열의 조건을 충족하기에 길이는 4*2 = 8입니다.
이 때 r은 어떠한 자연수가 되든 상관이 없습니다.
따라서 [ak, r] 쌍을 찾는데 중요한 것은 ak-1과 ak 사이의 거리가 얼마인지, 그리고 이 ak-1이 자신을 기준으로 왼쪽에 있는 원소를 잡아먹었는지, 또는 오른쪽에 있는 원소를 잡아먹었는지를 알기만 하면 됩니다. "값이 아닌 거리 차이를 분석하는 것" 이것이 제일 중요한 포인트 입니다.
예를 들어 [3,1,1,3,5,1,1]에서 a를 1이라고 하면, [3,a1,a2,3,5,a3,a4]가 됩니다. 이제 풀어볼까요?
그렇다면 가장 많은 [ak, r] 순서쌍을 가지는 ak는 무엇일까요? 여기에 그냥 탐욕법을 넣자는 겁니다.
배열 a를 순회하여, 다음의 정보를 저장해야 합니다.
그 다음에 "값 p의 개수"를 기준으로 정렬을 1번 합니다.
이렇게 하면 저희는 숫자가 제일 많은 p부터 p가 존재하는 인덱스 목록을 활용하여 [ak, r] 순서 쌍을 찾을 수 있습니다. 그리고 어느 순간 숫자 p의 전부가 순서쌍이 된 스타 수열의 길이가 answer보다 작게 되면, 이 때 이 answer를 반환하면 끝입니다.
이렇게 풀면 시간 초과가 나지 않을까요? 하지만 나지 않습니다. 왜냐하면 고유한 숫자의 개수 * 이 숫자들이 반복되는 횟수의 합이 곧 배열 a의 길이이기 때문입니다.
예를 들어 숫자가 1부터 50만 까지 전부 있다고 하면, 모든 숫자는 오로지 1번만 반복됩니다. 그래서 double-for 루프를 돌려도 O(N)과 다를 바가 없습니다.
반대로 숫자가 1부터 1000까지 있고, 각 숫자가 500번 반복된다고 해도, 첫 번째 루프는 천 번 돌고, 두 번째 루프는 500번 돌기 때문에 O(N)입니다.