KDLiam

[Programmers 코딩 기초 트레이닝 : Java] 수열과 구간 쿼리 2 본문

Problems(Java)/Programmers

[Programmers 코딩 기초 트레이닝 : Java] 수열과 구간 쿼리 2

KDLiam 2025. 10. 13. 15:22

🔗 문제 링크

프로그래머스 181923 - 조건에 맞는 최소값 찾기


💡 문제 요약

  • 정수 배열 arr과 2차원 배열 queries가 주어집니다.
  • 각 쿼리 [s, e, k]에 대해 arr[s..e]에서 k보다 큰 값 중 최소값을 찾습니다.
  • 해당 값이 없으면 -1을 반환합니다.
  • 모든 쿼리 결과를 배열로 반환합니다.

예:
arr = [1,3,5,7,9], queries = [[0,2,2],[1,4,6]]

  1. arr[0..2]에서 2보다 큰 값 중 최소 → 3
  2. arr[1..4]에서 6보다 큰 값 중 최소 → 7
    결과 → [3,7]

🧩 처음 작성한 코드

class Solution {
    public int[] solution(int[] arr, int[][] queries) {
        
        int[] answer = new int[queries.length];  
        int current = 0;
        
        for(int[] query : queries) {
            int minValue = 10000000;
            for(int i=query[0];i<=query[1];i++) {
                if((arr[i] > query[2]) && (minValue>=arr[i])) {
                    minValue = arr[i];
                }
            }
            
            if(minValue == 10000000) {
                answer[current] = -1;
            } else {
                answer[current] = minValue;
            }
            
            current += 1;
        }
        
        return answer;
    }
}

💡 문제점 및 개선 포인트

  1. current 변수를 굳이 사용하지 않아도 됨
  2. 10000000 → Integer.MAX_VALUE 사용하면 의미가 명확
  3. 삼항연산자를 활용하면 조건문을 한 줄로 표현 가능
  4. 변수 이름을 의미 있게 바꾸면 코드 이해도 ↑

🧩 개선한 코드

 
class Solution {
    public int[] solution(int[] arr, int[][] queries) {
        int[] answer = new int[queries.length];

        for(int i = 0; i < queries.length; i++) {
            int s = queries[i][0];
            int e = queries[i][1];
            int threshold = queries[i][2];

            int minValue = Integer.MAX_VALUE;
            for(int j = s; j <= e; j++) {
                if(arr[j] > threshold && arr[j] < minValue) {
                    minValue = arr[j];
                }
            }

            answer[i] = (minValue == Integer.MAX_VALUE) ? -1 : minValue;
        }

        return answer;
    }
}

✅ 개선 포인트

  • current 제거 → 코드 간결
  • 상수 10000000 → Integer.MAX_VALUE 사용 → 의미 명확
  • 변수 이름 s, e, threshold → 쿼리 의미 직관적
  • 삼항연산자 → 조건문 한 줄로 표현 → 가독성 ↑
  • 성능 동일: O(q * L)
    • q = 쿼리 수
    • L = 각 쿼리 범위 길이

4️⃣ Optional: Java Stream 사용

 
import java.util.Arrays;

class Solution {
    public int[] solution(int[] arr, int[][] queries) {
        return Arrays.stream(queries).mapToInt(q -> {
            int s = q[0], e = q[1], k = q[2];
            return Arrays.stream(arr, s, e + 1)
                         .filter(x -> x > k)
                         .min()
                         .orElse(-1);
        }).toArray();
    }
}
  • 장점: 선언적 코드로 흐름 한눈에 파악 가능
  • 단점: 초보자에게는 다소 복잡
  • 성능: 범위 길이 짧으면 차이 없음, 범위 길면 스트림 오버헤드 존재