1주차 1차 2 - LeetCode-Study-Team/solutions GitHub Wiki

70 Climbing Stairs / Easy / Dynamic Programming

class Solution {
    private final static int[] caseStore = new int[46];
    public int climbStairs(int n) {
        if(n==0 || n==1 || n==2){
            caseStore[n] = n;
            return caseStore[n];
        }
        if(caseStore[n] > 2) {
            return caseStore[n];
        }
        caseStore[n] = climbStairs(n-1) + climbStairs(n-2);
        return caseStore[n];
    }
}

< 용어 정리 >

다이나믹 프로그래밍(Dynamic Programming)

특정 범위까지의 값을 구하기 위해서 그것과 다른 범위까지의 값을 이용하여 효율적으로 값을 구하는 알고리즘 설계 기법이다. 동적 계획법 답을 구하기 위해서 했던 계산을 또 하고 또 하고 계속해야 하는 종류의 문제에서 효과를 발휘한다. 이광근 교수의 저서 "컴퓨터 과학이 여는 세계"에서는 다이나믹 프로그래밍을 본질적인 의미를 더 살려서 기억하며 풀기로 더욱 적절하게 번역하였다.

분할 정복

분할 정복 알고리즘(Divide and conquer algorithm)은 그대로 해결할 수 없는 문제를 작은 문제로 분할하여 문제를 해결하는 방법이나 알고리즘이다.

동적 계획법과 분할 정복의 공통점과 차이점

[공통점] 문제를 작은 단위로 쪼개서 분할하여 접근함

[차이점] 동적 계획법은

  1. 중복되는 부분 문제가 상위 문제를 해결하는데 사용됨
  2. 메모이제이션을 활용

분할 정복은

  1. 부분 문제가 서로 중복되지 않음
  2. 메모이제이션을 활용하지 않음

출처 exp_blog [https://syujisu.tistory.com/147] (https://syujisu.tistory.com/147)

메모이제이션(Memoization)

컴퓨터 프로그래밍 용어로, 동일한 계산반복해야 할 경우 한 번 계산한 결과를 메모리에 저장해 두었다가 꺼내 씀으로써 중복 계산을 방지할 수 있게 하는 기법이다. 동적 계획법의 핵심이 되는 기술로써 결국 메모리라는 공간 비용을 투입해 계산에 소요되는 시간 비용을 줄이는 방식이다.

133 Clone Graph / medium / Graph

public Node cloneGraph(Node root) {  //root : 복제 대상 노드
    if (root == null) return null;

    // use a queue to help BFS
    Queue<Node> queue = new LinkedList<Node>();
    queue.add(root);

    // use a map to save cloned nodes
    Map<Node, Node> map = new HashMap<Node, Node>();

    // clone the root
    map.put(root, new Node(root.val));

    while (!queue.isEmpty()) {
        Node node = queue.poll();  //poll() : 첫번째 값을 반환, 비어있다면 null 반환

        // handle the neighbors
        for (Node neighbor : node.neighbors) {
            if (!map.containsKey(neighbor)) {
                // clone the neighbor
                map.put(neighbor, new Node(neighbor.val));
                // add it to the next level
                queue.add(neighbor);
            }

            // copy the neighbor
            map.get(node).neighbors.add(map.get(neighbor));
        }
    }

    return map.get(root);
}

BFS(Breath-First Search)

너비 우선 탐색 특정 노드에서 시작해서 인접한 노드를 먼저 탐색하는 방식

DFS(Depth-Fisrt Search)

깊이 우선 탐색 깊이 갈 수 있는 만큼 최대한 가고, 더이상 갈 곳이 없다면 이전 정점으로 돌아가는 방식

큐(Queue)

먼저 들어온 데이터가 먼저 나가는 선입선출 방식의 자료구조

정점(vertice)

노드라고도 하며, 정점에는 데이터가 저장된다 (0, 1, 2, 3, 4)

엣지(edge)

정점을 잇는 선 엣지로 연결된 두 정점은 서로 알고있다는 관계를 의미

언다이렉트 그래프(undirected Graph)

엣지의 방향성이 없는 그래프

(정점1, 정점2)와 (정점2, 정점1)이 동일하다.

깊은 복사(Deep copy)

데이터 자체를 복사하는 것 복사된 두 객체는 완전히 독립적인 메모리를 차지한다 객체의 참조값이 아닌 실제 값을 복사하여 새로운 객체를 만들어 내는 것

얕은 복사(Shallow copy)

객체의 참조값(주소값)을 복사하는 것 복사한 객체의 속성을 변경하면 원본 객체에도 영향을 준다

57 Insert Interval / medium / Interval

class Solution {
    public int[][] insert(int[][] intervals, int[] newInterval) {

        int len = intervals.length;
        int newLen = newInterval.length;
        if(len == 0 && newLen == 0) { return new int[][]{}; }
        if(len == 0 && newLen != 0) { return new int[][]{newInterval}; }
        if(len != 0 && newLen == 0) { return intervals; }

        List<int[]> store = new ArrayList<>();

        int start = newInterval[0];
        int end = newInterval[1];

        int index = 0;
        while (index < len && start > intervals[index][1]) {
            store.add(new int[]{intervals[index][0], intervals[index][1]});
            index++;
        }        

        int left = newInterval[0];
        int right = newInterval[1];
        while (index < len && end >= intervals[index][0]) {
            left = Math.min(left, intervals[index][0]);
            right = Math.max(right, intervals[index][1]);            
            index++;
        }        
        store.add(new int[]{left, right});

        while (index < len) {
            store.add(new int[]{intervals[index][0], intervals[index][1]});
            index++;
        }

        int[][] new_intervals = new int[store.size()][2];        
        for(int i=0; i<store.size(); i++){
            new_intervals[i] = store.get(i);
        }

        return new_intervals;
    }
}

영화배우가 영화를 선택하는 방법

  1. Shortest Interval

가장 구간이 짧은 영화들을 우선적으로 선택

  1. Eariest Left Endpoint

영화의 시작이 가장 왼쪽에 있는 영화를 우선적으로 선택

  1. Eariest Right Endpoint

영화가 끝나는 시점이 가장 왼쪽에 있는 영화를 우선적으로 선택 최적의 해 구할 수 있음

각 방법의 시간복잡도

  1. 구간이 가장 짧은 영화 : O(n^2)
  2. 끝나는 시점에서 가장 빨리 시작하는 영화 : O(n^2)
  3. 끝나는 시점에서 가장 빨리 끝나는 영화 : O(nlogn)

시간 복잡도

가장 간단한 정의는 알고리즘의 성능 알고리즘의 수행해야 하는 연산의 횟수를 수치화 한 것

빅오 표기법(Big-O)

빅오 표기법은 불필요한 연산을 제거하여 알고리즘 분석을 쉽게 할 목적으로 사용된다. 빅오 복잡성에는 시간복잡도와 공간복잡도가 있다 시간복잡도 : N의 크기에 따라 실행되는 조작의 수 공간복잡도 : 알고리즘이 실행될 때 사용하는 메모리의 양

⚠️ **GitHub.com Fallback** ⚠️