15565 귀여운 라이언

문제 이해

1,2만 존재하는 수열이 있다.
이 때, 연속된 구간 중 1이 K개 이상 있는 배열 중 가장 짧은 길이를 구하는 것이 문제이다.


문제 풀이

1이 K개 이상 있는 배열을 구하는 문제이다.
1이 몇 번 나왔는지에 따라 배열의 길이를 줄일지, 혹은 늘릴지 결정할 수 있을 것이다.

우리는 left, right 포인터를 설정할 것이고, 초기 위치는 index = 0위치이다.
그리고 두 포인터는 아래와 같은 조건 때 움직인다.

  1. left : 구간에 1이 K개 나왔다면, 오른쪽으로 이동한다. 이 때 한 칸만 이동하는 것이 아닌, 다시 arr[left] = 1이 되는 구간까지 증가시켜야 한다.

  2. right : 구간에 1이 K개 미만으로 나왔다면, 오른쪽으로 이동한다. 이 때 한 칸만 이동하는 것이 아닌 arr[right] = 1이 되는 구간까지 증가시켜야 한다.

left, right의 이동에 대해서 조금 더 자세히 알아보자.

1 2 1 2 1이라는 수가 있다고 생각하자.
만약, right = 4이고, left = 0 이였을 때 left를 1 증가시켜야 하는 경우이다.
하지만, 2 1 2 1이든 1 2 1이든 1이 2번 나오는 것은 동일하다.
우리는 최소의 구간 길이를 구하고 싶기 때문에 1 2 1이 답이 될 것이다.

즉, 최소의 구간 길이는 "시작" 부분도 1이고, "종료" 부분도 1인 구간의 길이가 될 것이다.
따라서 index = 2인 곳까지 이동시킨 후 알고리즘을 수행한다.
right도 동일한 이유로 arr[right] = 1이 되는 구간까지 이동시켜 줘야 한다.

마지막으로, right이 배열의 끝을 가리키고 있더라도 left는 아직 움직일 수 있다. 따라서 while문을 추가시켜주어 가능한 최대로 left를 오른쪽으로 이동시켜줄 필요가 있다.


코드

import java.io.*;
import java.util.*;

public class Main {
	
	static int N, K;
	static Integer[] arr;
	static int[] alpha = new int[26];
	
	static void two_pointer() {
		int left = 0;
		int right = 0;
		int sum = 0;
		int length = Integer.MAX_VALUE;
		
		while(right < N) {
			if(sum<K) {
				if(arr[right]==1) {
                /*
                arr[right] = 1이 될 때 까지는 계속 right++만 수행될 것이다.
                arr[right] = 1이 된 순간 연속된 배열에 1이 1개 추가된 것이므로
                sum을 1증가시킨다.
                */
					sum++;
				}
				right++;
			}
			else {
            /*
            arr[left] = 1이 될 때 까지는 계속 left++만 수행될 것이다.
            arr[left] = 1이 된 순간, 연속된 배열에 1이 1개 빠지므로, 
            sum을 1 감소시킨다.
            또한, sum >= K인 상황이므로, 정답이 될 가능성이 있는 후보이다.
            
            따라서 원래 저장되어 있던 길이와 이 길이를 비교하여 
            작은 값으로 갱신한다.
            */
				if(arr[left]==1) {
					length = Math.min(length,right - left);
					sum--;
				}
				left++;
			}
		}
		
		while(left < N) {
			if(sum<K) break;
			if(arr[left]==1) {
				length = Math.min(length,right - left);
				sum--;
			}
			left++;
		}
		if(length==Integer.MAX_VALUE) System.out.println(-1);
		else System.out.println(length);
	}
	
	public static void main(String[] args) {

		FastReader sc = new FastReader();

		N = sc.nextInt();
		K = sc.nextInt();
		
		arr= new Integer[N];
		for(int i =0;i<N;i++) {
			arr[i] = sc.nextInt();
		}

		two_pointer();
	}
	
	static class FastReader // 빠른 입력을 위한 클래스
}

결과

  • 2번째 틀렸습니다 이유 : 정답이 존재하지 않을 가능성이 있다고 문제에서 명시했지만, 그런 경우의 수를 체크하지 않아서 틀렸다.

좋은 웹페이지 즐겨찾기