백준 20437 - 문자열게임2 (Java)

Mendel·2024년 5월 21일

알고리즘

목록 보기
49/85

문제 접근

주어진 조건을 만족하는 연속된 문자열에 대한 모든 탐색이 필요하다. 이런 경우는 전형적인 투포인터 문제다.
우리가 구해야하는 것은
1. 임의의 문자를 K개 포함하고 있는 연속된 구간의 최소 길이
2. 임의의 문자를 K개 포함하고 있는 연속된 구간의 최대 길이(단, 이때의 최대길이를 측정할 때는 양끝이 동일한 해당 문자여야 한다.)

여기서, 우리가 알아야할 것은 1,2를 구하는 과정이 크게 다를것이 없다는 것임.
어차피 최소길이를 구한다는 것 자체가 양끝에 동일한 해당 문자가 와야한다.
또한, 각 문자를 기준으로 탐색을 할 때, 문자는 어차피 소문자 26개이므로 거의 선형 탐색을 따르는 투포인터를 26번 수행한다고 시간복잡도를 절대 초과할 일이 없다.

문제 풀이

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

class Main {
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        int T = Integer.parseInt(br.readLine());
        StringBuilder sb = new StringBuilder();
        for (int t = 0; t < T; t++) {
            String W = br.readLine();
            int K = Integer.parseInt(br.readLine());
            int[] results = find(W, K);
            if (results[0] == -1 && results[1] == -1) {
                sb.append(-1).append('\n');
            } else {
                sb.append(results[0]).append(" ").append(results[1]).append('\n');
            }
        }
        System.out.print(sb);
    }

    private static int[] find(String W, int K) {
        int[] result = new int[2];
        int resultsMax = 0;
        int resultsMin = W.length() + 1;
        for (int c = 'a'; c <= 'z'; c++) {
            int count = 0;
            int i = 0;
            for (int j = 0; j < W.length(); j++) {
                if (W.charAt(j) == c) {
                    count++;
                    if (count >= K) {
                        while (!(W.charAt(i) == c && count == K)) {
                            if (W.charAt(i) == c) count--;
                            i++;
                        }
                        resultsMax = Math.max(resultsMax, j - i + 1);
                        resultsMin = Math.min(resultsMin, j - i + 1);
                    }
                }
            }
        }

        result[0] = (resultsMin == W.length() + 1) ? -1 : resultsMin;
        result[1] = (resultsMax == 0) ? -1 : resultsMax;
        return result;
    }
}

profile
이것저것(안드로이드, 백엔드, AI, 인프라 등) 공부합니다

0개의 댓글