2 λΆ„ μ†Œμš”

πŸ“š ALGORITHM


πŸ“š μŠ¬λΌμ΄λ”© μœˆλ„μš° ( Sliding Window )

μŠ¬λΌμ΄λ”© μœˆλ„μš° λž€?

μŠ¬λΌμ΄λ”© μœˆλ„μš°λž€ κ³ μ • μ‚¬μ΄μ¦ˆμ˜ μœˆλ„μš°κ°€ μ΄λ™ν•˜λ©΄μ„œ μœˆλ„μš° 내에 μžˆλŠ” 데이터λ₯Ό μ΄μš©ν•΄ 문제λ₯Ό ν’€μ΄ν•˜λŠ” μ•Œκ³ λ¦¬μ¦˜μ„ λ§ν•œλ‹€.
λ°°μ—΄μ΄λ‚˜ 리슀트 μš”μ†Œμ˜ 일정 λ²”μœ„ 값을 비ꡐ할 λ•Œ μ‚¬μš©ν•˜λ©΄ 맀우 μœ μš©ν•˜λ‹€.
μ›λž˜ λ„€νŠΈμ›Œν¬μ—μ„œ μ‚¬μš©λ˜λ˜ μ•Œκ³ λ¦¬μ¦˜μ„ λ¬Έμ œν’€μ΄μ— μ‘μš©ν•œ κ²½μš°μ΄λ‹€.

투 포인터와 λΉ„μŠ·ν•œλ°, 일반적으둜 κ³ μ • μ‚¬μ΄μ¦ˆ μœˆλ„μš°λ₯Ό μ‚¬μš©ν•˜λŠ” 경우λ₯Ό μŠ¬λΌμ΄λ”© μœˆλ„μš°λΌ κ΅¬λΆ„ν•˜κΈ°λ„ ν•œλ‹€. 그리고 투 ν¬μΈν„°λŠ” μ •λ ¬λœ 배열을 λŒ€μƒμœΌλ‘œ ν•˜λŠ”λ° μŠ¬λΌμ΄λ”© μœˆλ„μš°λŠ” 관계없이 ν™œμš©λœλ‹€.



μŠ¬λΌμ΄λ”© μœˆλ„μš° μ˜ˆμ‹œ 문제

πŸ“ [JUNGOL_2577] νšŒμ „ 초λ°₯
이 문제의 풀이λ₯Ό 톡해 μ˜ˆμ‹œλ₯Ό 보여주겠닀.

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.Queue;
import java.util.StringTokenizer;

public class main{
	static StringTokenizer st;
	static int N, d, k, c;
	static int answer = Integer.MIN_VALUE;

	public static void main(String[] args) throws IOException {
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

		st = new StringTokenizer(br.readLine(), " ");
		// μ ‘μ‹œ 수
		N = Integer.parseInt(st.nextToken());
		// 초λ°₯의 κ°€μ§“μˆ˜
		d = Integer.parseInt(st.nextToken());
		// μ—°μ†ν•΄μ„œ λ¨ΉλŠ” μ ‘μ‹œμ˜ 수
		k = Integer.parseInt(st.nextToken());
		// 쿠폰 번호
		c = Integer.parseInt(st.nextToken());

		// N+k 인 μ΄μœ λŠ” μ›ν˜•μ΄κΈ° λ•Œλ¬Έ
		int[] arr = new int[N+k];
		// 먹은 초λ°₯ λ°°μ—΄
		int[] check = new int[d+1];

		// 초λ°₯ μž…λ ₯λ°›κΈ°
		for (int i = 0; i < N; i++) {
			arr[i] = Integer.parseInt(br.readLine());
		}
		
		// 뒀에 더 μΆ”κ°€ ( μ›ν˜•μ΄κΈ° λ•Œλ¬Έμ— )
		for(int i=N; i<N+k; i++) {
			arr[i] = arr[i-N];
		}
		
		int ans = -1;
		// 쿠폰에 ν•΄λ‹Ήλ˜λŠ” 초λ°₯ μ ‘μ‹œμ˜ 개수
		int cnt = 0;
		int coupon = 0;	
				
		// μŠ¬λΌμ΄λ”© μœˆλ„μš° μ‚¬μš©
		for(int i=0; i<N+k; i++) {
			// μ ‘μ‹œ k개λ₯Ό μ„ νƒν•œ μƒνƒœμ—μ„œ λ‹€μŒ μ„ νƒμœΌλ‘œ λ„˜μ–΄κ°”μ„λ•Œ
			if(i>=k) {
				// 맨 λ’€ μ ‘μ‹œλΉΌκΈ°
				if(--check[arr[i-k]] == 0) cnt--;
				if(arr[i-k] == c) coupon--;
			}
			
			// ν˜„μž¬ μ ‘μ‹œ μΆ”κ°€
			if(++check[arr[i]] == 1) cnt++;
			if(arr[i] == c) coupon++;
			if(i>=k)
				ans = Math.max(ans, coupon == 0 ? cnt+1 : cnt);
		}
		System.out.println(ans);
	}
}


λ¬Έμ œλŠ” 크게 어렡지 μ•Šλ‹€.
쿠폰이 μžˆλŠ”λ° λ§Œμ•½ μΏ ν°λ²ˆν˜Έκ°€ 적힌 초λ°₯을 ν¬ν•¨ν•΄μ„œ μ—°μ†μœΌλ‘œ k 개 먹으면 총 k개 초λ°₯을 먹을 수 μžˆλŠ” 것이고
μΏ ν°λ²ˆν˜Έκ°€ 적힌 초λ°₯을 μ œμ™Έν•˜κ³  μ—°μ†μœΌλ‘œ k개 먹으면 총 k+1개 초λ°₯을 먹을 수 μžˆλŠ” 것이닀.
λ¬Όλ‘  μ—°μ†μœΌλ‘œ μ•ˆλ¨ΉλŠ” κ²½μš°λ„ μžˆλ‹€. κ·ΈλŸ¬λ‚˜ 그런 κ²½μš°μ—λŠ” 쿠폰에 μžˆλŠ” 초λ°₯을 λͺ»λ¨ΉκΈ° λ•Œλ¬Έμ— μ΅œλŒ€κ°’μ„ κ΅¬ν•΄μ•Όν•˜λŠ” μž…μž₯μœΌλ‘œμ„œ κ³ λ €ν•˜μ§€ μ•Šμ•„λ„ 될 사항이닀.
μ—¬κΈ°μ„œ μ€‘μš”ν•œ 것은 λ§Œμ•½ 같은 번호의 초λ°₯이 2κ°œμ΄μƒ ν•œ 그룹에 μžˆλŠ” 것이닀.
κ·Έ λ•Œ 초λ°₯ 개수 μΉ΄μš΄νŒ…μ„ μ–΄λ–»κ²Œ ν•΄μ€˜μ•Όν•˜μ§€ κ³ λ―Όν•˜λ‹€κ°€ μ•„μ˜ˆ ν¬ν•¨ν•˜μ§€ μ•Šμ•˜λ‹€. 넣어주지도 μ•Šμ•˜κ³  μΉ΄μš΄νŒ…ν•΄μ£Όμ§€λ„ μ•Šμ•˜λ‹€.
μ•½κ°„ 빈자리 같은 λŠλ‚ŒμœΌλ‘œ ? 사싀 μ—°μ‚°μ—λŠ” λ‹€ 포함 λ˜μ–΄ μžˆμ§€λ§Œ κ²‰μœΌλ‘œλ³΄λ©΄ ν¬ν•¨λ˜μ–΄ μžˆμ§€ μ•Šμ€ λŠλ‚Œμ΄λ‹€.
κΈ°μ‘΄ 초λ°₯ λ°°μ—΄κ³Ό 먹은 초λ°₯ 배열을 λ‚˜λˆ„κ³  μ „μœ„μ—°μ‚°μžλ₯Ό μ‚¬μš©ν•˜μ—¬ μ’€ 더 μ½”λ“œλ₯Ό κ°„λ‹¨νžˆ ν•˜μ˜€λ‹€.
이 ν’€μ΄μ—μ„œ μŠ¬λΌμ΄λ”© μœˆλ„μš°λ₯Ό μ‚¬μš©ν•˜μ˜€λŠ”λ° 주석에 달린 것 처럼 μ„ νƒν•˜λŠ” indexκ°€ k개 이상이 λ˜μ—ˆμ„ λ•Œ 맨 λ’€ μ ‘μ‹œ ν•˜λ‚˜λ₯Ό λΉΌμ£Όκ³  ν˜„μž¬ μ ‘μ‹œλ₯Ό λ”ν•΄μ£Όμ—ˆλ‹€.
ꡳ이 int 배열이 μ•„λ‹ˆλ”λΌλ„ queue λ‚˜ λ‹€λ₯Έ λ°©λ²•μœΌλ‘œ 해도 상관이 없을 것 κ°™λ‹€.
였히렀 가독성이 더 쒋을 μˆ˜λ„.. μ „μœ„ μ—°μ‚°μž, ν›„μœ„ μ—°μ‚°μžλ₯Ό μ‚¬μš©ν•˜μ—¬ 가독성이 쒋지 μ•Šμ§€λ§Œ μ‹œκ°„μ€ ν™•μ‹€νžˆ λΉ λ₯Έ 것 κ°™λ‹€.