[백준] 11003_최솟값 찾기 - JAVA

2023. 4. 22. 18:38·알고리즘/알고리즘 유형
반응형

백준_11003

 

11003번: 최솟값 찾기

N개의 수 A1, A2, ..., AN과 L이 주어진다. Di = Ai-L+1 ~ Ai 중의 최솟값이라고 할 때, D에 저장된 수를 출력하는 프로그램을 작성하시오. 이때, i ≤ 0 인 Ai는 무시하고 D를 구해야 한다.

www.acmicpc.net

 

덱(deque)

위 문제는 슬라이딩 윈도우와 정렬을 사용하면 될 것 같지만 정렬은 nlog(n)의 시간 복잡도를 가지고, N과 L의 범위가 5,000,000인 이 문제에서는 정렬을 사용할 수 없다. O(n)의 시간 복잡도로 해결해야 한다. 정렬 대신 슬라이딩 윈도우와 덱(deque)이란 자료구조를 사용하면 이 문제를 풀 수 있다.

출처 : https://soft.plusblog.co.kr/24

덱은 양 끝에서 데이터를 삽입하거나 삭제할 수 있는 자료구조이다. 왼쪽에서는 addFirst(), removeFirst() 함수가 삽입, 삭제 역할을 하고, 오른쪽에서는 addLast(), removeLast() 함수가 삽입, 삭제 역할을 한다.

덱은 (값, 인덱스) 형태의 노드를 클래스로 구현하여 저장한다. 새로운 노드가 저장될 때 기존 덱이 가지고 있는 뒤에 있던 노드부터 차례로 비교를 시작한다. 만약 기존에 있던 노드보다 새로운 노드의 값이 더 작다면 기존에 있던 노드는 덱에서 제거(removeLast) 된다. 이런식으로 비교를 반복하다가 최솟값을 찾을 때, 덱의 제일 앞에 있는 노드를 선택해 반환하면 된다. 즉, 덱 처음에 있는 노드가 최솟값이다.

 

코드

import java.io.*;
import java.util.Deque;
import java.util.LinkedList;
import java.util.Scanner;
import java.util.StringTokenizer;

public class Main {
    public static final Scanner sc = new Scanner(System.in);
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
        StringTokenizer st = new StringTokenizer(br.readLine());
        StringBuilder sb = new StringBuilder();

        int n = Integer.parseInt(st.nextToken());
        int l = Integer.parseInt(st.nextToken());
        st = new StringTokenizer(br.readLine());
        Deque<Node> myDeque = new LinkedList<>();

        for(int i = 0; i < n; i++) {
            int now = Integer.parseInt(st.nextToken());
            while(!myDeque.isEmpty() && myDeque.getLast().value > now) {
                myDeque.removeLast();
            }
            myDeque.addLast(new Node(now, i));
            if(myDeque.getFirst().index <= i - l) {
                myDeque.removeFirst();
            }
            sb.append(myDeque.getFirst().value).append(" ");
        }
        bw.write(sb.toString());
        bw.flush();
        bw.close();
    }

    static class Node {
        public int value;
        public int index;

        Node(int value, int index) {
            this.value = value;
            this.index = index;
        }
    }
}

 

제출 결과

영겁의 시간 끝에 드디어 통과되었다. 덱이라는 자료구조 자체를 처음 접해봤어서 내 힘으로는 도저히 풀 수 없는 문제라 코드를 처음부터 보면서 코드를 공부한다는 느낌으로 풀었다. 그런데 교재에 나와있는 정답이 시간초과가 뜨는 바람에 더 이것저것 찾아보았다. 내가 직접 푼 문제면 금방 해결했었을텐데.. 아무튼 교재에서는 최솟값을 붙이는 과정에서 '최솟값 + " "' 이런 식으로 코드가 작성되어 있었다. 그래서 StringBuilder로 코드를 수정했더니 통과되었다! 로직 자체는 막 어렵지 않은 거 같은데 처음 보는 클래스들이 너무 많다; 공부 열심히 더 해야지.

 

 

반응형
저작자표시 비영리 변경금지 (새창열림)
'알고리즘/알고리즘 유형' 카테고리의 다른 글
  • [백준] 17298_오큰수 - JAVA
  • [백준] 1874_스택 수열 - JAVA
  • [백준] 12891_DNA 비밀번호 - JAVA
  • [백준] 2018_수들의 합5 - JAVA
데부한
데부한
어차피 할 거면 긍정적으로 하고 싶은 개발자
    반응형
  • 데부한
    동동이개발바닥
    데부한
  • 전체
    오늘
    어제
    • 분류 전체보기 (307)
      • 방통대 컴퓨터과학과 (27)
        • 잡담 (9)
        • 3학년1학기 (17)
      • 프로젝트 및 컨퍼런스 회고 (1)
        • 프로젝트 (4)
        • 한이음 프로젝트 (0)
        • 회고 (3)
      • 공부 (165)
        • Spring (37)
        • JPA (71)
        • 인프런 워밍업 클럽_BE (10)
        • Java (6)
        • React.js (27)
        • 넥사크로 (11)
        • 기타 (3)
      • 알고리즘 (85)
        • 알고리즘 유형 (10)
        • 알고리즘 풀이 (57)
        • SQL 풀이 (18)
      • 에러 해결 (13)
      • 잡담 (7)
        • 국비교육 (2)
        • 구매후기 (5)
        • 진짜 잡담 (0)
  • 블로그 메뉴

    • Github
    • Linkedin
    • 홈
    • 방명록
    • 글쓰기
    • 관리
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    react
    코딩테스트
    SQL
    인프런
    자바스크립트
    운영체제
    백준
    SpringBoot를 이용한 RESTful Web Service 개발
    IT
    기출문제
    egov
    토이프로젝트
    Java
    프로그래머스
    넥사크로
    MSA
    JPA
    oracle
    프론트엔드
    RESTful
    전자정부프레임워크
    Spring
    개발자
    QueryDSL
    에러해결
    방통대
    토비의스프링부트
    스프링부트
    알고리즘
    springboot
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
데부한
[백준] 11003_최솟값 찾기 - JAVA
상단으로

티스토리툴바