[백준] 10818번(Java/자바)

Yeoonnii·2022년 9월 5일
0
post-custom-banner

백준 10818번 최소, 최대

🧾 구현 1

Scanner 사용하여 구현

  1. 배열의 길이 length입력받기
  2. for반복문 length만큼 실행
    2-1. 주어진 N개의 정수 배열에 넣기
    2-2. 변수 maxmin 정의
  3. for반복문 한번 더 실행
    3-1. max > arr[j] 인 경우 max = arr[j];
    3-2. min > arr[j] 인 경우 min = arr[j];
  4. minmax 출력

💻제출 코드 1

import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int length = sc.nextInt();
        int[] arr = new int[length];

        for (int i = 0; i < length; i++) {
            arr[i] = sc.nextInt();
        }
        int max = arr[0];
        int min = arr[0];

        for (int j = 0; j < length; j++) {
            if (max < arr[j]) {
                max = arr[j];
            }
            if (min > arr[j]) {
                min = arr[j];
            }
        }
        System.out.println(min);
        System.out.println(max);
        sc.close();
    }
}

💡 다른 풀이방법

🌎 배열을 사용하지 않고 + BufferedReader를 사용한 문제풀이 링크
풀이 완료 후 다른 풀이를 찾아보던 중 배열을 사용하지 않고 + BufferedReader를 사용하여 문제를 풀이한 글을 보게 되었다

해당 글에서는 배열을 사용하게 되는 경우 생기는 문제점 2가지를 지적했다

  1. 메모리를 많이 차지하며
  2. 배열의 원소 정렬시 최악의 경우 시간복잡도가 N^2 이 되기 때문에 불필요하게 시간을 낭비한다

시간과 메모리를 적게 낭비하지 않는 해결법은

  1. 배열을 사용하지 않으며
  2. 입력받은 문자를 배열에 담지 않고 즉시 비교한다
    ➡️ 이때는 시간복잡도가 N이되며, 따로 입력받은 문자를 정렬할 필요가 없어 시간을 단축시킬 수 있다고 했다

🧾 구현 2

BufferedReader 사용하여 구현

  1. readLine() 을 통해 입력 받는 경우 공백도 같이 입력되기 때문에
    ➡️ StringTokenizer를 이용해 공백을 분리 한다
    * readLine() = 한 줄을 읽는 메소드

  2. br.readLine()st.nextToken()은 반환값이 String이기 때문에 Integer.parseInt()를 이용하여 int형으로 변환시켜준다

  3. 문제에서 모든 정수는 -1,000,000보다 크거나 같고, 1,000,000보다 작거나 같은 정수라고 되어있기 때문에 비교를 위해 max 에는 범위를 초과한 가장 작은 값으로, min 에는 범위를 초과한 가장 큰 값으로 초기화 한다
    * max = 범위를 초과한 제일 작은값으로 설정해 주어야 입력되는 값과 비교/갱신된다
    * min = 범위를 초과한 제일 큰 값으로 설정해 주어야 입력되는 값과 비교/갱신된다

  4. while문에 hasMoreTokens()사용하여 입력받은 정수들을 inputnum에 한번씩 저장하기 위해 StringToken 에 들어있는 모든 토큰들이 없어질 때까지 배열에 모두 담는다
    ➡️ hasMoreTokens() = StringTokenizer 에 토큰이 남아있으면 true, 비어있으면 false를 반환

  5. while문에서 각 토큰을 가져와 기존 max 값보다 큰지, 기존 min 값보다 작은지 비교하고, 비교 결과에 따라 max와 min에 값을 대입하여 반복문을 실행한다

💻제출 코드 2

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;

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

        Integer.parseInt(br.readLine());
        StringTokenizer st = new StringTokenizer(br.readLine()," ");

        int max = -1000001;
        int min = 1000001;

        while(st.hasMoreTokens()){
            int inputnum = Integer.parseInt(st.nextToken());
            if(inputnum > max){
                max = inputnum;
            }
            if(min > inputnum){
                min = inputnum;
            }
        }
        System.out.println(min + " " + max);
    }
}

💡 '제출 코드1'과 '제출 코드2'의 메모리와 처리시간 비교

결과적으로 시간은 3배 정도 빨라졌고, 메모리는 3.5배 정도 줄어들었다
메모리와 처리속도 면에서 월등히 BufferedReader가 우수한것을 확인 할 수 있다

또한 배열을 사용하면 최악의 경우 시간복잡도가 O(N^2) 이지만 배열을 사용하지 않고 즉시 비교하는 경우 시간복잡도가 O(N) 이므로 훨씬 시간이 단축된다고 한다

앞으로 문제를 풀어나갈때 배열을 반드시 사용해야하는 경우는 배열을 이용하여 풀이를 하고,
배열을 반드시 사용하지 않아도 되는 경우에는 즉시 비교하는 방법을 이용하는것이 좋겠다

또한 ScannerBufferedReader도 장단점을 비교하여 상황에 따라 선택하여 사용해야겠다

post-custom-banner

0개의 댓글