문제

홍대병에 걸린 도현이는 겹치는 것을 매우 싫어한다. 특히 수열에서 같은 원소가 여러 개 들어 있는 수열을 싫어한다. 도현이를 위해 같은 원소가 K개 이하로 들어 있는 최장 연속 부분 수열의 길이를 구하려고 한다.

 100,000 이하의 양의 정수로 이루어진 길이가 N인 수열이 주어진다.  이 수열에서 같은 정수를 K개 이하로 포함한 최장 연속 부분 수열의 길이를 구하는 프로그램을 작성해보자.

 

 

 

입력

첫째 줄에 정수 N(1 ≤ N ≤ 200000)과 K(1 ≤ K ≤ 100)가 주어진다.

둘째 줄에는 a1, a2, ... , an이 주어진다. (1 ≤ ai ≤ 100000)

 

 

 

출력

조건을 만족하는 최장 연속 부분 수열의 길이를 출력한다.

 

 


 

 

문제 해결

 

이중 for문을 이용한 브루트포스 알고리즘은 탐색 범위를 나름대로 최적화 후 제출해봤지만 아쉽게도 실행 시간 초과가 발생했습니다.

따라서 투 포인터를 이용하여 해결 가능합니다.

 

start와 end라는 두 개의 포인터가 입력된 수열 ary를 순차적으로 탐색하게 됩니다.

 

end ≤ N를 만족하면 다음 내용을 반복합니다.

1. 먼저 end가 ary의 첫 원소부터 이동합니다.

2. 만약 end가 탐색하는 값 t의 개수가 K개보다 커지면, start는 t의 개수가 K개보다 작거나 같아질 때까지 이동합니다.

3. end - start +1개와 현재 최대값을 비교하여 최대값을 갱신합니다.

 

 

 

코드

#include <iostream>
using namespace std;

int ans, n, k, ary[200001], cnt[100001];

int main() {
	cin >> n >> k;

	for (int i = 1; i <= n; i++) scanf("%d", ary + i);

	int start = 1, end = 0;

	while (end < n) {
		end++;
		cnt[ary[end]]++;

		if (cnt[ary[end]] > k)
			while (cnt[ary[end]] > k) {
				cnt[ary[start]]--;
				start++;
			}
		
		ans = max(ans, end - start + 1);
	}

	cout << ans;
}

'🎲 BOJ > 🥇' 카테고리의 다른 글

[C++] 백준 5430 : AC  (0) 2023.08.06
[C++] 백준 4256 : 트리  (0) 2023.08.06
[C++] 백준 1072 : 게임  (0) 2022.02.08
[C++] 백준 2533 : 사회망 서비스(SNS)  (0) 2022.02.07

+ Recent posts