코딍코딍
코딩기록
코딍코딍
전체 방문자
오늘
어제
  • 분류 전체보기 (271)
    • 개발 (2)
    • Java (1)
    • 스프링 (28)
    • JPA (11)
    • Git (3)
    • 알고리즘 (160)
      • 백준 (132)
      • 프로그래머스 (8)
      • SWEA (20)
    • 토이 프로젝트 (14)
      • 간단한 Springboot CRUD (1)
      • 게시판 프로젝트 (13)
    • 알고리즘 개념정리 (8)
    • 오류 해결 (13)
    • 보류 (0)
    • AWS (5)
    • 트러블 슈팅 (0)
    • 회고 (3)
    • CS (4)

블로그 메뉴

  • 홈
  • 태그
  • 방명록

공지사항

최근 글

티스토리

hELLO · Designed By 정상우.
코딍코딍

코딩기록

알고리즘/백준

18870번 : 좌표 압축

2022. 7. 27. 22:39

https://www.acmicpc.net/problem/18870

 

18870번: 좌표 압축

수직선 위에 N개의 좌표 X1, X2, ..., XN이 있다. 이 좌표에 좌표 압축을 적용하려고 한다. Xi를 좌표 압축한 결과 X'i의 값은 Xi > Xj를 만족하는 서로 다른 좌표의 개수와 같아야 한다. X1, X2, ..., XN에 좌

www.acmicpc.net

 

 

문제

 

 

코드

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

public class Main {
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
        StringBuilder sb = new StringBuilder();
        int n = Integer.parseInt(br.readLine());
        StringTokenizer st = new StringTokenizer(br.readLine()," ");

        //O(n)
        ArrayList<Integer> input = new ArrayList(n);
        for(int i=0;i<n;i++) {
            input.add(Integer.parseInt(st.nextToken()));
        }

        HashSet<Integer> inputSet = new HashSet<>(input); //중복값 제거
        Integer[] newArr = inputSet.toArray(new Integer[0]);
        Arrays.sort(newArr);

        HashMap<Integer, Integer> map = new HashMap<>();
        for(int i=0;i<inputSet.size();i++) {
            map.put(newArr[i],i);
        }

        //O(n)
        for(int i=0;i<n;i++) {
            sb.append(map.get(input.get(i)) + " ");
        }
        bw.write(sb+""); bw.flush();

    }
}

 

 

해결방법

많은 시도 끝에 푼 문제이다. 처음에 그냥 ArrayList 2개를 사용해 하나는 값을 입력받고, 하나는 중복된 값빼고 오름차순 정렬하여 값을 입력받은 ArrayList와 비교하여 출력하는 식으로 풀었다. 나름 속도를 높인다고 BufferedReader, BufferedWriter, StringBuilder, StringToken을 사용했지만 "시간 초과"가 떴다.

 

 

ArrayList 2개 사용한 코드 (시간 초과)

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

public class Main {
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
        StringBuilder sb = new StringBuilder();
        int n = Integer.parseInt(br.readLine());
        StringTokenizer st = new StringTokenizer(br.readLine()," ");

        ArrayList<Integer> input = new ArrayList(n);
        ArrayList<Integer> inputSort = new ArrayList(n);
        //O(n^2)
        for(int i=0;i<n;i++) {
            int num = Integer.parseInt(st.nextToken());
            input.add(num);
            if(!inputSort.contains(num))
                inputSort.add(num);
        }
        Collections.sort(inputSort);
        
        //O(n^2)
        for(int i=0;i<n;i++) {
            sb.append(inputSort.indexOf(input.get(i)) + " ");
        }
        bw.write(sb+""); bw.flush();
    }
}

 

머리 속을 스쳐간 생각으로 HashSet이나 HashMap을 사용해도 속도는 비슷할 것이라고 생각했다. 하지만 HashSet과 HashMap을 사용하면 속도는 훨씬 빨라진다. 이를 몰랐던 이유는 자바 컬렉션들의 시간 복잡도에 대해 무지했기 때문이다. 자바 컬렉션(HashMap, List, ...)들의 시간복잡도가 궁금하다면 여기를 클릭하자.

 

 

1. 시간 초과난 코드는 중복된 값을 제거할 때 contains()를 써서 빅오가 O(n^2)이 된다. 위에 있는 정답 코드처럼 중복된 값을 제거할 때 HashSet을 써서 중복된 값을 제거해야 빅오가 O(n)이 된다.

 

2. 시간 초과난 코드는 출력값을 생성할 때 indexOf()를 써서 빅오가 O(n^2)이 된다. 위에 있는 정답 코드처럼 HashMap을 생성하여 get()를 사용해 찾아야 빅오가 O(n)이 된다. 

 

 

 

'알고리즘 > 백준' 카테고리의 다른 글

1758번 : 알바생 강호  (0) 2022.07.29
11279번 : 최대 힙  (0) 2022.07.28
2012번 : 등수 매기기  (0) 2022.07.26
2839번 : 설탕 배달  (0) 2022.07.24
18310번 : 안테나  (0) 2022.07.23
    '알고리즘/백준' 카테고리의 다른 글
    • 1758번 : 알바생 강호
    • 11279번 : 최대 힙
    • 2012번 : 등수 매기기
    • 2839번 : 설탕 배달
    코딍코딍
    코딍코딍
    ㅎ2

    티스토리툴바