홍대병에 걸린 도현이는 겹치는 것을 매우 싫어한다.
특히 수열에서 같은 원소가 여러 개 들어 있는 수열을 싫어한다.
도현이를 위해 같은 원소가 개 이하로 들어 있는 최장 연속 부분 수열의 길이를 구하려고 한다.
이하의 양의 정수로 이루어진 길이가 인 수열이 주어진다.
이 수열에서 같은 정수를 개 이하로 포함한 최장 연속 부분 수열의 길이를 구하는 프로그램을 작성해보자.
첫째 줄에 정수 ()과 ()가 주어진다.
둘째 줄에는 이 주어진다 ()
조건을 만족하는 최장 연속 부분 수열의 길이를 출력한다.
처음 지문을 봤을 때 최장 연속 부분 수열의 길이라는 지문을 읽고
이게 뭐지? LIS인가?
최장 연속 부분 수열이 뭐지?
하면서 문제를 읽어도 잘 이해가 되지 않았습니다.
어렵게 생각하지 않고 단순하게 부분 수열이라는 것을 읽고
전체 수열에서 연속되는 부분 수열이 최대가 되도록 하는 것을 구하면 되지 않을까?
라고 생각하고 입력과 출력을 확인하니 이해가 됐습니다.
이해한 후에는 투 포인터를 사용하면 될 것 같다는 생각이 들었습니다.
단순 투 포인터 문제이기 때문에 투 포인터 알고리즘을 학습했다면 방법을 간단하게 떠올리실 수 있습니다.
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;
class Main {
static StringTokenizer st;
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
st = new StringTokenizer(br.readLine());
int N = Integer.parseInt(st.nextToken());
int K = Integer.parseInt(st.nextToken());
int[] arr = new int[N];
st = new StringTokenizer(br.readLine());
for (int i = 0; i < N; i++) {
arr[i] = Integer.parseInt(st.nextToken());
}
int start = 0;
int end = 0;
int max = 1;
int[] counting = new int[100001];
while (end < N) {
int num = arr[end];
if (counting[num] == K) {
counting[arr[start]]--;
start++;
}
else {
counting[num]++;
end++;
max = Math.max(max, end - start);
}
}
System.out.println(max);
}
}
이 문제에서 while의 조건에서 왜 start < N은 제외했냐하면
start 인덱스가 증가하는 조건을 확인해보면 알 수 있는데
특정 숫자의 개수가 K개 이상일 때만 start 인덱스가 증가하기 때문에
end 인덱스보다 클 수가 없는 상황이기 떄문에 제외했습니다!