ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 자알인 (1) 코딩테스트 팁
    자료구조와 알고리즘/알고리즘 2024. 1. 3. 00:56

     

     

    - 연습장과 필기도구를 준비하는 것이 좋다 

    - 코드 스피넷을 만들어두면 좋다 : 본인이 어려웠던 알고리즘 위주, 복습과 원리를 학습하는 차원에서도 좋고, 사용할 수 있다면, 빠르게 가져올 수 있음 

    - 타임아웃오류 : 자바는 거의 자유로우나, 자바의 컬렉션을 사용하면 타임아웃이 발생하는 경우도 있으니 조심하자

    - 예외처리 조심하자 (null값 참조 등 -> 실수하는경우 종종 발생)

    - 본인만의 시간제한을 두고 푸는 연습을 하는 편이 좋다

    - REPL로 코드를 검증하는 연습도 해두면 좋다고함! 

     

    2. 자바 자료형

     

    -> 속도면에서 당연히 원시자료형이 연산이 빠름 

     ex) 배열에 데이터 1억개 집어넣고, 찾는 연산 -> 원시(int -> 삽입:128밀리초,탐색:26밀리초, Integer:847밀리초, 46밀리초)

    -> int로 배열을 생성하면 newarray, Integer배열 생성시 anewarray => 각각 신규배열,신규참조배열 생성 -> 메모리 4배가량 차이남 

     

    List ->  ArrayList:동적배열구현 시쿼스 형태 

               LinkedList: 연결리스트 구현 자료형, 이중 연결리스트로 되어있다.

               Set과 Queue도 같은 Collection을 상속받아서, 동일한 메서드들 있음 

     

    Map -> HashMap: 해시테이블 구조 자료형, 입력순서 보장 x

            -> LinkedHashMap: 입력 순서 보장하는 해쉬맵

            -> TreeMap: 값을 순서에 따라 정렬 -> 내부적으로 자가 균형 이진 탐색 트리 (레드-블랙트리)임

    * TreeMap과 HashMap은 내부 구현만 다르고, 인터페이스 동일 

     

    BigInteger : 무한대 숫자 크기를 저장할 수 있는 자료형 -> 계산속도가 느리다는 단점 존재!

     

    2.1 컬렉션 프레임워크의 속도

     

    List<Integer> listElements = new ArrayLtst<>();
    for (int t = 0; i. < 100000000 - 1; t++)
    listElements.add(1);
    listElements.add(2);
    // ArrayLtstcInteger그 1억 개 중 찾기
    listElements.contains(2);
    
    
    //삽입속도 : 2791,밀리초  탐색속도:98밀리초

    -> 참조자료형이자 동적 배열 > 동적배열은 배열의 크기가 넘어가는 숫자를 저장하기 위해 초기값의 1.5배씩 배열의 크기를 늘림(더블링)

    -> 만약 처음부터 ArrayList의 크기를 크게 한다면 더블링 과정이 사라져 좀 더 빠르게 삽입가능

     

    3. 빅오 

     

    - 빅오는 점진적 실행시간을 표기하기 위한 방법 (입력값 n에 따른 실행시간)

    - 구체적인 연산 횟수보다 입력값에 따른 알고리즘 실행시간 추이만 따진다.

     

    O(1) : 입력 값이 커져도, 실행 시간이 일정함

    public int big1(int n){
    	return 42;
    }

    ex) 배열에서 값을 조회할 때, 연결리스트의 끝에 값을 삽입할 때

     

     

    O(logn) : 입력값을 계속 반으로 나눈다고 생각해보자 -> 연산횟수는 log2N과 같다  

    while(n>1)
    	n =/ 2;
    return n;

    ex) 이진 탐색

     

     

     

    O(N): 정확하게 입력값 만큼 실행 -> 실행 시간이 선형으로 늘어남 -> 선형 시간 알고리즘

    ex) 정렬되지 않은  리스트에서 최댓값,최솟값을 찾는 경우 

     

    O(nlogN) : 입력값을 순회하며, logn연산이 곱해짐 (입력값 만큼 순회하면서, 각 순서에 해당하는 값 반으로 계속 나누기)

    for (Int i = 0; i < n; i++) {
    while (n > 1)
    n /= 2;
    n = r;
    }

    ex)병합정렬을 비롯한, 효율적인 정렬 알고리즘들이 위와 같은 빅오를 가짐 

    O(n)과 거의 비슷한 성능

     

    O(n^2) : 중첩으로 반복하면서 하는 연산 

    ex) 버블정렬 

    -> 대부분 코테에서 알고리즘 최적화라 한다면, N^2을 nlogn으로 바꾸는 작업들이다.

     

    O(2^n) : 입력값의 크기만큼  2배씩 연산함 -> 시간 복잡도가 아주 구림 

    ex)피보나치 재귀적 구현 

     

    O(n!) :  입력값 순회하면서, 다시 값을 줄이며 재귀호출 -> 가장 구린 알고리즘 n이 100만되어도 못씀 

    public int fn(int n) {
    for (int i = 0; i < n; i++)
    fn(n - 1);
    return n;
    }

     

    3.1 빅오를 계산하는 실용적인 방법

     

    -> 정확하게 계산하는 방법은 count같은걸 넣어서 ++하고 종료시 출력해보기

    -> 분할상한분석: 최악의 경우의 빅오를 여러 번에 걸쳐 나눠주는 형태로 알고리즘 시간복잡도 계산 

    -> 병렬화 

     

     

    4. 자바 컬렉션 프레임워크와 빅오 

     

     

    '자료구조와 알고리즘 > 알고리즘' 카테고리의 다른 글

    완탐  (0) 2024.04.12
    자알인 - 스택 & 큐  (0) 2024.01.30
    다이나믹 프로그래밍  (0) 2023.04.13
    여러가지 수학  (0) 2023.04.11
    스택과 문제들 풀면서 얻은..  (0) 2023.04.05
Designed by Tistory.