<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>Emily0_0</title>
        <link>https://velog.io/</link>
        <description>룰루랄라</description>
        <lastBuildDate>Fri, 20 Nov 2020 02:25:26 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <image>
            <title>Emily0_0</title>
            <url>https://images.velog.io/images/emily0_0/profile/246712c9-2706-4d67-9067-60eb76a4e3f7/_.jpeg</url>
            <link>https://velog.io/</link>
        </image>
        <copyright>Copyright (C) 2019. Emily0_0. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/emily0_0" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[[OS] 인터럽트]]></title>
            <link>https://velog.io/@emily0_0/OS-%EC%9D%B8%ED%84%B0%EB%9F%BD%ED%8A%B8-fbb8e7jp</link>
            <guid>https://velog.io/@emily0_0/OS-%EC%9D%B8%ED%84%B0%EB%9F%BD%ED%8A%B8-fbb8e7jp</guid>
            <pubDate>Fri, 20 Nov 2020 02:25:26 GMT</pubDate>
            <description><![CDATA[<h2 id="인터럽트란">인터럽트란?</h2>
<blockquote>
<p>프로그램을 실행하는 도중에 예기지 않은 상황이 발생할 경우 현재 실행중인 작업을 즉시 중단하고 발생된 상황을 우선 처리한 후 실행중이던 작업으로 복귀하여 계속 처리하는 것</p>
</blockquote>
<h2 id="인터럽트의-종류와-발생-원인">인터럽트의 종류와 발생 원인</h2>
<h3 id="외부-인터럽트">외부 인터럽트</h3>
<blockquote>
<p>입출력장치, 타이밍 장치, 전원 등 외부적인 요인에 의해 발생하는 인터럽트</p>
</blockquote>
<p><strong>전원 이상 인터럽트</strong> : 정전이되거나 전원 이상이 있는경우 발생
<strong>기계 착오 인터럽트</strong> : CPU의 기능적인 오류 동작이 발생한 경우 발생
<strong>외부 신호 인터럽트</strong> : 타이머에 의해 규정된 시간을 알리는경우, 키보드로 인터럽트 키를 누른 경우, 외부 장치로부터 인터럽트 요청이 있는 경우 발생
<strong>입출력 인터럽트</strong> : 입출력 Data의 오류나 이상 현상이 발생한 경우, 입출력장치가 데이터의 전송을 요구하거나 전송을 끝났음을 알릴 경우 발생</p>
<h3 id="내부-인터럽트trap">내부 인터럽트(Trap)</h3>
<blockquote>
<p>잘못된 명령이나 데이터를 사용할 때 발생하는 인터럽트</p>
</blockquote>
<p><strong>프로그램 검사 인터럽트</strong> : 0으로 나누기가 발생한 경우, OverFlow 또는 UnderFlow가 발생한경우, 프로그램에서 명령어를 잘못 사용한 경우, 부당한 기억장소의 참조와 같은 프로그램 상의 오류가 발생</p>
<h3 id="소프트웨어-인터럽트">소프트웨어 인터럽트</h3>
<blockquote>
<p>프로그램 처리 중 명령의 요청에 의해 발생하는 인터럽트</p>
</blockquote>
<p><strong>SVC인터럽트</strong> : 사용자가 SVC명령을 써서 의도적으로 호출한 경우, 복잡한 입출력 처리를 해야하는 경우, 기억장치 할당 및 오퍼레이터와 대화를 해야하는 경우 발생</p>
<h2 id="인터럽트-발생-시-처리과정">인터럽트 발생 시 처리과정</h2>
<p><img src="https://images.velog.io/images/emily0_0/post/25b575bb-9db5-4f33-819b-0c365a6e1c6e/image.png" alt=""></p>
<ol>
<li>프로그램 실행을 중단한다.</li>
<li>현재의 프로그램 상태를 보존한다.</li>
<li>인터럽트 처리 루틴을 실행한다.</li>
<li>인터럽트 서비스 루틴을 실행한다.
5, 인터럽트 요청 신호가 발생했을 때 보관한 PC의 값을 다시 PC에 저장한다.</li>
<li>PC의 값을 이용하여 인터럽트 발생 이전에 수행중이던 프로그램을 계속 실행한다.</li>
</ol>
<h2 id="참고-사이트">참고 사이트</h2>
<p><a href="https://coding-factory.tistory.com/353">인터럽트의 정의와 종류 및 처리과정</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[알고리즘] 정리]]></title>
            <link>https://velog.io/@emily0_0/%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98-%EC%A0%95%EB%A6%AC</link>
            <guid>https://velog.io/@emily0_0/%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98-%EC%A0%95%EB%A6%AC</guid>
            <pubDate>Wed, 18 Nov 2020 06:37:50 GMT</pubDate>
            <description><![CDATA[<h2 id="radix-sort">Radix Sort</h2>
<p>낮은 자리수부터 비교하여 정렬해 간다는 것을 기본 개념으로 하는 정렬 알고리즘
비교 연산을 하지 않으며 정렬 속도가 빠르다.
데이터 전체 크기에 Radix Table 크기의 메모리가 더 필요하다.</p>
<h3 id="정렬-방식">정렬 방식</h3>
<ol>
<li>0~9 까지의 Bucket(Queue 자료구조의)을 준비한다.</li>
<li>모든 데이터에 대하여 가장 낮은 자리수에 해당하는 Bucket에 차례대로 데이터를 둔다.</li>
<li>0부터 차례대로 버킷에서 데이터를 다시 가져온다.</li>
<li>가장 높은 자리수를 기준으로 하여 자리수를 높여가며 2번 3번 과정을 반복한다.</li>
</ol>
<h3 id="예시">예시</h3>
<p><img src="https://images.velog.io/images/emily0_0/post/11af3120-3010-42a9-94b5-1de95a5d0e57/image.png" alt=""></p>
<p>각 숫자에 해당하는 큐 공간을 할당하고 진행한다.</p>
<p><img src="https://images.velog.io/images/emily0_0/post/370e9e65-9497-4aa6-83ae-0ea065472566/image.png" alt=""></p>
<p>먼저 1의 자리 숫자부터 시도한다. 데이터 순서대로 각 1의 자리에 해당되는 Queue에 데이터가 들어가게 된다. 15같은 경우는 1의 자리가 5이므로 Queue 5에 들어가는 방식이다.</p>
<p><img src="https://images.velog.io/images/emily0_0/post/54a4e292-9d99-4386-970b-898145122b6c/image.png" alt=""></p>
<p>1의 자리 정렬이 완료되면, 10의 자리에 대해 같은 작업을 반복한다.</p>
<p><img src="https://images.velog.io/images/emily0_0/post/d11d3355-a37c-4743-bb01-c9983de76229/image.png" alt=""></p>
<p>각 데이터의 10의 자리에 해당되는 큐에 데이터를 위치시킨다.
0번 큐부터 차례대로 데이터를 가지고 온다.</p>
<p><img src="https://images.velog.io/images/emily0_0/post/603061cd-89a1-42aa-8b2a-dd4dea28c1e6/image.png" alt=""></p>
<p>최종 정렬이 완료된다.</p>
<h3 id="특징">특징</h3>
<p>시간복잡도는 O(dn). d는 가장 큰 숫자의 자리수
자리수가 고정되어 있어서 안정성이 있다.</p>
<h2 id="위상정렬-topological-sort">위상정렬 (Topological sort)</h2>
<blockquote>
<p>방향 그래프에 존재하는 각 정점들의 선행 순서를 위배하지 않으면서 모든 정점을 나열하는 것.</p>
</blockquote>
<p>하나의 방향 그래프에는 여러 위상 정렬이 가능하다.
위상 정렬의 과정에서 선택되는 정점의 순서를 위상 순서(Topological Order)라고 한다.
위상 정렬의 과정에서 그래프에 남아있는 정점 중에 진입 차수가 0인 정점이 없다면, 위상 정렬 알고리즘이 중단되고, 이러한 그래프로 표현된 문제는 실행이 불가능한 문제가 된다.</p>
<h3 id="위상정렬을-이용한-기본적인-해결-방법">위상정렬을 이용한 기본적인 해결 방법</h3>
<p><img src="https://images.velog.io/images/emily0_0/post/67b687f1-8a11-4ab0-8ab5-6878b72d6491/image.png" alt=""></p>
<ol>
<li>진입 차수가 0인 정점(즉, 들어오는 간선의 수가 0)을 선택한다.
진입 차수가 0인 정점이 여러 개 존재할 경우 어느 정점을 선택해도 무방하다.
초기에 간선의 수가 0인 모든 정점을 큐에 삽입한다.</li>
<li>선택된 정점과 여기에 부속된 모든 간선을 삭제한다.
선택된 정점을 큐에서 삭제한다.
선택된 정점에 부속된 모든 간선에 대해 간선의 수를 감소한다.</li>
<li>위의 과정을 반복해서 모든 정점이 선택, 삭제되면 알고리즘 종료한다.</li>
</ol>
<h2 id="허프만-코드">허프만 코드</h2>
<p>가변 길이 코드를 만들어서 효율적으로 압축한다.</p>
<h3 id="예제">예제</h3>
<p>문자열 &quot;ABBCCCDDDDEEEEEFFFFFF&quot;의 가변 길이 코드 만들기 </p>
<ol>
<li><p>알파벳 별 빈도수를 저장한 노드를 생성한다.
<img src="https://images.velog.io/images/emily0_0/post/43b50d38-6dba-45fb-8a65-a416084c974c/image.png" alt=""></p>
</li>
<li><p>빈도수를 비교하여 노드를 만든다.
가장 작은 빈도수를 가진 노드와 두 번째로 작은 빈도수의 노드를 합쳐 노드를 만든다.
<img src="https://images.velog.io/images/emily0_0/post/970ac496-df3a-412b-90fb-15a84fad168d/image.png" alt=""></p>
</li>
<li><p>2를 반복한다.
<img src="https://images.velog.io/images/emily0_0/post/eb1b4d1e-1a34-47ca-b75c-a5bc8ee5ee1d/image.png" alt=""></p>
</li>
</ol>
<h3 id="결과">결과</h3>
<p><img src="https://images.velog.io/images/emily0_0/post/4a245423-f3e6-493c-8608-1df94eeb1244/image.png" alt=""></p>
<p>만들어진 허프만 코드를 가지고 문자열을 인코딩한다.</p>
<h3 id="참고-사이트">참고 사이트</h3>
<p><a href="https://lktprogrammer.tistory.com/48">Radix Sort</a>
<a href="https://gmlwjd9405.github.io/2018/08/27/algorithm-topological-sort.html">위상 정렬</a>
<a href="https://withhamit.tistory.com/12">허프만 코드</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[Django란?]]></title>
            <link>https://velog.io/@emily0_0/Django%EB%9E%80</link>
            <guid>https://velog.io/@emily0_0/Django%EB%9E%80</guid>
            <pubDate>Wed, 18 Nov 2020 05:06:46 GMT</pubDate>
            <description><![CDATA[<h3 id="개요">개요</h3>
<p>이전에 Django로 프로젝트 했던 경험이 생각나지 않아서 Django에 대해 복습하기로 했다.</p>
<h3 id="django-프레임워크">Django 프레임워크</h3>
<p>Django는 <strong>파이썬으로 작성된 오픈소스 웹 애플리케이션 프레임워크</strong>로, <strong>Model-View-Controller(MVC)</strong> 패턴을 따르고 있다.
고도의 데이터베이스 기반 웹 사이트를 작성하는데 있어서 수고를 더는 것이 장고의 주된 목표이다.
컴포넌트의 <strong>재사용성(reusability)</strong>과 <strong>플러그인화 가능성(pluggability)</strong>, <strong>빠른 개발</strong>을 강조한다.
설정 파일부터 데이터 모델까지 파이썬으로 작성되어 있다.</p>
<h3 id="mvc--mvt">MVC / MVT</h3>
<p>MVC는 일반적인 프레임워크가 가지는 패턴이다. 장고는 MVT 패턴을 가진다.</p>
<blockquote>
<p><strong>Model</strong> : 데이터베이스 서버에 저장이 되는 데이터를 다룬다.
<strong>View</strong>, <strong>Template</strong>(Django) : 유저가 원하는 형태로 데이터를 적절하게 만들어서 보내주는 역할
<strong>Control</strong>, <strong>View</strong>(Django) : 사용자의 입력과 이벤트에 반응하여 Model과 View를 업데이트한다.</p>
</blockquote>
<p><strong>Model</strong>은 어플리케이션이 <strong>무엇</strong>을 할 지에 대한 정의한다. 처리되는 데이터, 데이터베이스, 내부 알고리즘 등 <strong>내부 비즈니스에 관한 로직의 처리를 수행</strong>한다.</p>
<p><strong>View</strong>는 사용자에게 보여지는 영역이다. JSP등 <strong>사용자 인터페이스를 담당</strong>한다.</p>
<p><strong>Controller</strong>는 모델에게 <strong>어떻게</strong>할 것인지를 알려주며, <strong>모델과 뷰 사이를 연결하는 역할</strong>을 한다. 사용자의 입출력을 받아 데이터를 처리한다.</p>
<p>MVC, MVT는 거의 동일하다.</p>
<table>
<thead>
<tr>
<th align="center">내용</th>
<th align="center">MVC</th>
<th align="center">MVT</th>
</tr>
</thead>
<tbody><tr>
<td align="center">데이터</td>
<td align="center">model</td>
<td align="center">model</td>
</tr>
<tr>
<td align="center">(사용자가 보는) 데이터의 구현</td>
<td align="center">view</td>
<td align="center">template</td>
</tr>
<tr>
<td align="center">사용자에게 보여주는 데이터에 대한 로직</td>
<td align="center">controller</td>
<td align="center">view</td>
</tr>
</tbody></table>
<h3 id="django-동작">Django 동작</h3>
<p><img src="https://images.velog.io/images/emily0_0/post/8b5822e1-1419-41f7-988d-27722c29493e/image.png" alt=""></p>
<ol>
<li>사용자가 브라우저에서 Url로 요청을 보낸다.</li>
<li>View가 요청을 확인하고 Model에게 알려준다.</li>
<li>Model은 DB에서 요청한 정보를 찾아서 View로 돌려준다.</li>
<li>View는 요청한 정보를 Templates에 전달하고 html과 조합되서 브라우저 사용자에게 보여진다.</li>
</ol>
<h3 id="django의-파일들">Django의 파일들</h3>
<p><img src="https://images.velog.io/images/emily0_0/post/86ac8c14-06f9-4683-98a1-5ec1d094d316/image.png" alt=""></p>
<p>녹색으로 표시된 파일이 개발자가 직접 다루는 파일이다.</p>
<h4 id="project">Project</h4>
<p>서비스 명 또는 서비스 자체를 말한다.
프로젝트를 만들면 기본 폴더와 파일이 생성된다.</p>
<h4 id="app">App</h4>
<p>웹 서비스에 추가되는 기능.
블로그, 게시판, 설문 등이 될 수 있다.
앱을 만들면 앱 이름으로 된 폴더에 기본 파일들이 생성된다.</p>
<h4 id="modelmodelspy">Model(models.py)</h4>
<p>앱을 만들면 해당 폴더 안에 models.py 파일이 생성된다.
파일에서 코드를 통해 모델(데이터)의 구조를 결정하고 관리할 수 있다.
데이터베이스와 관련된 다양한 동작을 수행한다.</p>
<h4 id="viewviewpy">View(view.py)</h4>
<p>실질적으로 파이썬 코드를 많이 작성하는 곳.
앱을 만들면 해당 폴더 안에 views.py 파일이 생성된다.
데이터를 어떻게 보여주고 처리할 것인지에 대한 로직을 짤 수 있다.
models.py에 신호를 보낸다.
주로 클래스 안에 http 메소드 함수를 포함하고 있다.</p>
<h4 id="templatehtml-file">Template(html file)</h4>
<p>데이터의 구현 부분
html 파일 안에 다양한 로직을 삽입할 수 있다.
사용자의 인터페이스에 적절하게 구성을 해주고, 그 정보가 web server로 간다.</p>
<h4 id="controller">controller</h4>
<p>일반적인 MVC 패턴에서 장고 view의 역할을 하는 영역이다.</p>
<h4 id="wsgiwsgipy">WSGI(wsgi.py)</h4>
<p>Web Server Gateway Interfase의 약자로 웹서버와 장고를 적절히 결합시켜준다.</p>
<h4 id="url-resolutionurlspy">URL Resolution(urls.py)</h4>
<p>wsgi.py에서 신호가 들어오면 가장 먼저 받는 곳이다.
정규표현식으로 구현되어 있다.</p>
<h4 id="asgi">asgi</h4>
<p>Asynchronous Server Gateway Interface의 약자로 wsgi가 동기식이라면 asgi는 동기, 비동기식 모두를 지원한다.</p>
<h3 id="참고-사이트">참고 사이트</h3>
<p><a href="https://medium.com/wasd/django%EB%A1%9C-%EA%B0%84%EB%8B%A8%ED%95%9C-%EB%B8%94%EB%A1%9C%EA%B7%B8-%EB%A7%8C%EB%93%A4%EA%B8%B0-1-%EA%B0%9C%EC%9A%94-%ED%94%84%EB%A1%9C%EC%A0%9D%ED%8A%B8-%EA%B5%AC%EC%84%B1-83d03ec74395">Make a Simple Blog with Django(1)</a>
<a href="https://medium.com/wasd/%EA%B0%84%EB%8B%A8%ED%95%98%EA%B2%8C-%EC%82%B4%ED%8E%B4%EB%B3%B4%EB%8A%94-rest-api-79422dfc0a7d">REST API</a>
<a href="https://velog.io/@swhybein/django-%ED%94%84%EB%A0%88%EC%9E%84%EC%9B%8C%ED%81%AC-%EA%B4%80%EB%A0%A8-%EC%9A%A9%EC%96%B4%EC%A0%95%EB%A6%AC">Django란?</a>
<a href="https://velog.io/@ybnr_92/Django-%EA%B0%9C%EB%85%90%EC%A0%95%EB%A6%AC">장고 개념 정리</a>
<a href="https://invalueable.tistory.com/100">장고 동작원리</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[자료구조] 정리]]></title>
            <link>https://velog.io/@emily0_0/%EC%9E%90%EB%A3%8C%EA%B5%AC%EC%A1%B0-%EC%A0%95%EB%A6%AC</link>
            <guid>https://velog.io/@emily0_0/%EC%9E%90%EB%A3%8C%EA%B5%AC%EC%A1%B0-%EC%A0%95%EB%A6%AC</guid>
            <pubDate>Wed, 18 Nov 2020 01:32:05 GMT</pubDate>
            <description><![CDATA[<h3 id="postfix">Postfix</h3>
<p><img src="https://images.velog.io/images/emily0_0/post/ab825dfd-51e5-420a-91f2-f4b1f6954711/image.png" alt=""></p>
<p><img src="https://images.velog.io/images/emily0_0/post/dcfa5eb8-efe8-4173-92e6-60f9cf50f9a3/image.png" alt=""></p>
<h3 id="prefix">Prefix</h3>
<p><img src="https://images.velog.io/images/emily0_0/post/49473066-f8cb-4b9d-8a08-65a0ce02aedc/image.png" alt=""></p>
<p><img src="https://images.velog.io/images/emily0_0/post/9d20d17d-fe31-4f56-811d-e0f1312e807f/image.png" alt=""></p>
<h3 id="순회">순회</h3>
<ul>
<li>전위 순회(preorder traverse) : 뿌리(root)를 먼저 방문</li>
<li>중위 순회(inorder traverse) : 왼쪽 하위 트리를 방문 후 뿌리(root)를 방문</li>
<li>후위 순회(postorder traverse) : 하위 트리 모두 방문 후 뿌리(root)를 방문</li>
<li>층별 순회(level order traverse) : 위 쪽 node들 부터 아래방향으로 차례로 방문</li>
</ul>
<h2 id="큐">큐</h2>
<h3 id="우선순위-큐">우선순위 큐</h3>
<p>큐는 연산의 결과로 먼저 들어간 데이터가 먼저 나오지만 우선순위 큐는 다르다. 
들어간 순서에 상관 없이 우선순위가 높은 데이터가 먼저 나온다. </p>
<h4 id="우선순위-큐를-구현하는-방법">우선순위 큐를 구현하는 방법</h4>
<ul>
<li>배열을 기반으로 구현하는 방법</li>
<li>연결리스트를 기반으로 구현하는 방법</li>
<li>힙을 이용하는 방법 -&gt; 주로 사용됨</li>
</ul>
<h3 id="선형-큐">선형 큐</h3>
<p>초기 상태의 공백 큐는 저장된 원소가 없으므로 front와 rear를 -1로 설정한다.
rear = n-1이면 포화상태</p>
<h3 id="원형-큐">원형 큐</h3>
<p>배열의 처음과 끝이 연결되어 있다고 생각하는 것
초기 공백 상태일 때 front와 rear값이 0
공백 상태 조건 front = rear
포화 상태 조건 (rear+1) % n = front
삽입 rear = (rear+1) % n
삭제 front = (front+1) % n</p>
<h3 id="dequeue">Dequeue</h3>
<p>큐의 양쪽 끝에서 삽입과 삭제가 모두 발생할 수 있는 큐. 
스택과 큐의 성질을 모두 가지고 있다.</p>
<h3 id="큐의-사용">큐의 사용</h3>
<p>작업 버퍼 큐, 프로세스 스케줄링, 대기 행렬을 모델링하는 시뮬레이션(큐잉이론)에서 사용한다.</p>
<h2 id="트리">트리</h2>
<p>비선형 자료구조 중에서 계층관계를 가진 계층형 자료구조</p>
<h3 id="이진트리">이진트리</h3>
<p>모든 노드가 2개의 서브 트리를 가지고 있는 트리</p>
<h3 id="포화-이진트리full-binary-tree">포화 이진트리(Full binary tree)</h3>
<p>높이가 5인 포화 이진트리의 노드 수 = 31개 </p>
<h3 id="완전-이진트리complete-binary-tree">완전 이진트리(Complete binary tree)</h3>
<p>레벨 1부터 k-1까지 노드가 채워져 있고 마지막 k에서는 왼쪽부터 오른쪽으로 노드가 순서대로 채워져 있는 이진트리</p>
<h2 id="minimum-spanning-tree">Minimum spanning tree</h2>
<p>spanning tree : 그래프의 모든 정점을 포함하는 트리 형태의 서브 그래프
Minimum spanning tree : 스패닝 트리 중에서 간선의 가중치 합이 가장 작은 스패닝 트리</p>
<h2 id="크루스칼-알고리즘">크루스칼 알고리즘</h2>
<p>무방향 연결 그래프가 주어질 때, 최소 스패닝 트리라고 부르는 서브 그래프를 찾는 알고리즘.
<a href="https://www.weeklyps.com/entry/%EC%9C%A0%EB%8B%88%EC%98%A8-%ED%8C%8C%EC%9D%B8%EB%93%9C-Unionfind">유니온 파인드</a> 자료구조를 사용한다.</p>
<ol>
<li><p>모든 간선을 끊어 놓는다.
<img src="https://images.velog.io/images/emily0_0/post/1df4f0db-dec6-4702-a871-0313f6d5e571/image.png" alt=""></p>
</li>
<li><p>가중치 순으로 간선을 정렬한다.
<img src="https://images.velog.io/images/emily0_0/post/83cdb9ff-9fac-480b-b1cf-aa62ff9b2467/image.png" alt=""></p>
</li>
<li><p>정렬된 간선을 순서대로 선택한다.</p>
</li>
<li><p>선택한 간선의 두 정점이 연결되어 있지 않으면, 해당 간선을 최소 스패닝 트리에 포함 시키고 두 정점을 연결한다.</p>
</li>
<li><p>3, 4 반복</p>
</li>
</ol>
<h3 id="결과">결과</h3>
<p><img src="https://images.velog.io/images/emily0_0/post/e6d536f4-8adf-4421-a0d7-49166e0b86f9/image.png" alt=""></p>
<h3 id="시간복잡도">시간복잡도</h3>
<p>간선 E개 정렬 = <code>O(elog₂e)</code>
union-find를 통한 vertex 비교 <code>O(V)</code>
따라서 <code>O(elog₂e)</code>
Edge 정렬이 적을수록 빠르다.</p>
<h2 id="프림-알고리즘">프림 알고리즘</h2>
<p>예시 그래프 
<img src="https://images.velog.io/images/emily0_0/post/b73fdcb3-2113-4ffc-b1c3-ea7a823c72d5/image.png" alt=""></p>
<ol>
<li><p>임의의 정점을 선택하여 비어있는 T에 포함시킨다. <code>T is tree</code>
<img src="https://images.velog.io/images/emily0_0/post/723c369a-c5bc-4fb6-9d15-8f47c44ecec9/image.png" alt=""></p>
</li>
<li><p>T에 있는 노드와 T에 없는 노드 사이의 간선 중 가중치가 최소인 간선을 찾는다.</p>
</li>
<li><p>찾은 간선이 연결하는 두 노드 중, T에 없는 노드를 T에 포함시킨다.
<img src="https://images.velog.io/images/emily0_0/post/acfa30d4-999d-494b-9f6b-3c5328b9cc6c/image.png" alt=""></p>
</li>
<li><p>모든 노드가 T에 포함될 때 까지 2,3을 반복한다.
<img src="https://images.velog.io/images/emily0_0/post/6ead5041-1170-4012-9b18-0ad9c4ec52c1/image.png" alt=""></p>
</li>
</ol>
<p><img src="https://images.velog.io/images/emily0_0/post/f8026453-d2dc-4ca7-b3bb-820232d9024d/image.png" alt=""></p>
<p><img src="https://images.velog.io/images/emily0_0/post/97e09930-0727-4cef-84da-c1aed399a567/image.png" alt=""></p>
<p><img src="https://images.velog.io/images/emily0_0/post/9cf999c3-6c38-4b83-a094-16dd5cd83504/image.png" alt=""></p>
<h3 id="시간복잡도-1">시간복잡도</h3>
<p>주 반복문이 정점의 수 n만큼 반복하고, 내부 반복문이 n번 반복하므로 <code>O(n^2)</code>
그래프에 간선이 많이 존재하는 ‘밀집 그래프(Dense Graph)’ 의 경우는 Prim 알고리즘이 적합하다.</p>
<h2 id="힙">힙</h2>
<p>최대힙, 최소힙
힙소트</p>
<h2 id="그래프">그래프</h2>
<p>연결되어있는 원소간의 관계를 표현하는 자료구조
연결할 객체를 나타내는 정점과 객체를 연결하는 간선의 집합으로 구성된다. 
그래프 G를 G=(V,E)로 정의하는데 V는 정점들의 집합, E는 간선들의 집합이다.</p>
<h3 id="그래프-구현-방법">그래프 구현 방법</h3>
<ul>
<li>순차 자료구조 방식 (인접 행렬)</li>
<li>연결 자료구조 방식 (인접 리스트)</li>
</ul>
<h3 id="dfs">DFS</h3>
<p>시작 정점에서 한 방향으로 갈 수 있는 가장 먼 경로까지 깊이 탐색하다가 더 이상 갈 곳이 없으면 가장 마지막에 만났던 갈림길 간전이 있는 정점으로 되돌아와서 다른 방향의 간선으로 재탐색</p>
<ul>
<li>스택사용</li>
</ul>
<h3 id="bfs">BFS</h3>
<p>시작 정점에서 인접한 정점들을 차례로 방문한 후 방문했던 정점을 다시 시작점으로 하여 인접한 정점들을 차례로 방문하는 방법.
가까운 정점을 먼저 방문하고 멀리있는 정점들은 나중에 방문하는 순회방법</p>
<ul>
<li>큐 사용</li>
</ul>
<h3 id="그래프-종류">그래프 종류</h3>
<h4 id="방향-그래프">방향 그래프</h4>
<h4 id="무방향-그래프">무방향 그래프</h4>
<h4 id="연결-그래프">연결 그래프</h4>
<h4 id="단절-그래프">단절 그래프</h4>
<h4 id="완전-그래프">완전 그래프</h4>
<h4 id="가중치-그래프">가중치 그래프</h4>
<h3 id="참고-사이트">참고 사이트</h3>
<p><a href="https://rhymestar.tistory.com/92">수기 표기법</a>
<a href="https://m.blog.naver.com/rlakk11/60159303809">순회</a>
<a href="https://www.weeklyps.com/entry/%ED%94%84%EB%A6%BC-%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98-Prims-algorithm">프림 알고리즘</a>
<a href="https://www.weeklyps.com/entry/%ED%81%AC%EB%A3%A8%EC%8A%A4%EC%B9%BC-%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98-Kruskals-algorithm">크루스칼 알고리즘</a>
<a href="https://myeonguni.tistory.com/12">자료구조 정리</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[프로그래머스] 스택/큐 - 프린터]]></title>
            <link>https://velog.io/@emily0_0/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-%EC%8A%A4%ED%83%9D%ED%81%90-%ED%94%84%EB%A6%B0%ED%84%B0</link>
            <guid>https://velog.io/@emily0_0/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-%EC%8A%A4%ED%83%9D%ED%81%90-%ED%94%84%EB%A6%B0%ED%84%B0</guid>
            <pubDate>Sat, 07 Nov 2020 03:51:16 GMT</pubDate>
            <description><![CDATA[<p><a href="https://programmers.co.kr/learn/courses/30/lessons/42587">프로그래머스 - 프린터</a></p>
<h3 id="문제-설명">문제 설명</h3>
<blockquote>
<p>대기목록에서 우선순위가 높은 문서부터 출력할 때, 내가 요청한 문서가 몇 번째로 인쇄되는지 <strong>return</strong> 하기</p>
</blockquote>
<h3 id="제한사항">제한사항</h3>
<blockquote>
<p>대기목록에는 1개 이상 100개 이하의 문서가 있다.
인쇄 작업의 중요도는 1~9로 표현하고, 숫자가 클수록 중요하다.
location은 대기목록의 index를 의미한다.</p>
</blockquote>
<h3 id="문제풀이">문제풀이</h3>
<blockquote>
<ol>
<li>대기목록에 맨 앞에 있는 문서보다 더 중요한 문서가 뒤에 있는지 확인한다.</li>
<li>더 중요한 문서가 뒤에 있으면 맨 앞의 문서를 맨 뒤로 보낸다.</li>
<li>더 중요한 문서가 없으면 맨 앞의 문서를 출력한다.</li>
</ol>
</blockquote>
<h3 id="코드">코드</h3>
<pre><code class="language-c">#include &lt;string&gt;
#include &lt;vector&gt;
#include &lt;list&gt;

using namespace std;

list &lt;pair&lt;int, int&gt;&gt; waiting_list;

void Make_list(vector&lt;int&gt; priorities){
    for(int i=0; i&lt;priorities.size(); i++){
        waiting_list.push_back(make_pair(i,priorities[i]));
    }
}

bool Is_first(){
    int front = waiting_list.front().second;
    bool is_first = true;

    list &lt;pair&lt;int, int&gt;&gt;::iterator iter;
    for(iter=waiting_list.begin(); iter!=waiting_list.end(); iter++){
        if(front &lt; iter-&gt;second){
            is_first = false;
            break;
        }
    }

    return is_first;
}

int solution(vector&lt;int&gt; priorities, int location) {
    int answer = 0;
    bool is_first;
    Make_list(priorities);

    while(1){
        is_first = Is_first();
        if(!is_first){
            pair&lt;int, int&gt; new_back = waiting_list.front();
            waiting_list.push_back(new_back);
        }
        else{
            answer ++;
            if(waiting_list.front().first == location) break;
        }
        waiting_list.pop_front();
    }

    return answer;
}</code></pre>
<h3 id="시간-복잡도">시간 복잡도</h3>
<p><strong>Worst case</strong> : 대기목록이 <code>descending order</code> 되어 있는 경우 + 맨 마지막 문서의 출력 순서를 <code>return</code>하는 경우
시간복잡도 : <code>O(N^2)</code>
<code>N : 대기목록의 크기</code></p>
<h3 id="스택큐-문제에-list를-사용한-이유">스택/큐 문제에 list를 사용한 이유</h3>
<p>처음에 큐를 사용하려고 했으나, 반복문으로 큐 안의 모든 원소들에게 접근해서 값을 확인해야 했다.
하지만 큐는 <code>index</code>를 사용해서 원소에 접근할 수 없어서 불편했다.
원소 접근이 많은 경우에는 스택/큐보다 <code>list</code>를 사용하면 <code>pop, push</code>가 자유롭고, <code>index</code>를 사용해서 원소에 접근할 수 있어서 더 편하다는 글을 보고 <code>list</code>를 사용하게 되었다.</p>
<h3 id="참고-사이트">참고 사이트</h3>
<p><a href="https://blockdmask.tistory.com/76">List of C++</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[프로그래머스] 스택/큐 - 다리를 지나는 트럭]]></title>
            <link>https://velog.io/@emily0_0/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-%EC%8A%A4%ED%83%9D%ED%81%90-%EB%8B%A4%EB%A6%AC%EB%A5%BC-%EC%A7%80%EB%82%98%EB%8A%94-%ED%8A%B8%EB%9F%AD</link>
            <guid>https://velog.io/@emily0_0/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-%EC%8A%A4%ED%83%9D%ED%81%90-%EB%8B%A4%EB%A6%AC%EB%A5%BC-%EC%A7%80%EB%82%98%EB%8A%94-%ED%8A%B8%EB%9F%AD</guid>
            <pubDate>Fri, 06 Nov 2020 05:40:42 GMT</pubDate>
            <description><![CDATA[<p><img src="https://images.velog.io/images/emily0_0/post/0b16e1ea-86db-4eeb-b5bc-bb9fa63e9345/Mitchell%20Funk%20-%20Cable%20Cars%20in%20Front%20of%20Bay%20Bridge%20at%20Dawn%20San%20Francisco.jpeg" alt=""></p>
<p><a href="https://programmers.co.kr/learn/courses/30/lessons/42583">프로그래머스 - 다리를 지나는 트럭</a></p>
<h3 id="문제-설명">문제 설명</h3>
<blockquote>
<p>트럭 여러대가 일차선 다리를 건널 때, <strong>모든 트럭이 다리를 건너기 위해 최소 몇 초가 걸리는지</strong> return 하기</p>
</blockquote>
<h3 id="제한사항">제한사항</h3>
<blockquote>
<p>트럭은 1초에 1만큼 움직인다.
다리의 길이는 <code>bridge_length</code>이다.
다리는 최대 <code>weight</code>만큼의 무게를 견딜 수 있다.
트럭은 대기하고 있는 순서대로 다리를 건넌다.</p>
</blockquote>
<h3 id="문제풀이">문제풀이</h3>
<blockquote>
<ol>
<li>트럭을 다리에 올릴 수 있는지 확인한다.</li>
<li>트럭에 다리를 올릴 수 있을 때
다리에 올라간 트럭 큐에 <code>push</code> 하고, 다리 위 트럭의 무게에 트럭의 무게를 추가한다.</li>
<li>트럭에 다리를 올릴 수 없을 때
다리가 채워지지 않았을 때 : 다리에 올라간 트럭 큐에 <code>0</code>을 추가한다.
다리가 꽉 찼을 때 : 다리에 올라간 트럭 큐의 맨 앞 트럭을 <code>pop</code> 한다.</li>
</ol>
</blockquote>
<h3 id="코드">코드</h3>
<pre><code class="language-c">#include &lt;string&gt;
#include &lt;vector&gt;
#include &lt;queue&gt;
using namespace std;

int solution(int bridge_length, int weight, vector&lt;int&gt; truck_weights) {
    int answer = 0;
    int idx = 0;

    queue&lt;int&gt; on_bridge;
    int on_bridge_weight = 0;

    while(1){
        if(idx == truck_weights.size()) break;

        int current_truck_weight = truck_weights[idx];
        answer ++;

        if(on_bridge.size() == bridge_length){
            on_bridge_weight -= on_bridge.front();
            on_bridge.pop();
        }

        if(on_bridge_weight + current_truck_weight &lt;= weight){
            on_bridge.push(current_truck_weight);
            on_bridge_weight += current_truck_weight;
            idx ++;
        }
        else{
            on_bridge.push(0);
        }
    }

    answer += bridge_length;
    return answer;
}</code></pre>
<p>맨 마지막 트럭이 다리 위로 올라가면 while문이 종료된다.
마지막 트럭이 다리 위로 올라간 다음, 다리를 빠져나올 때까지 <code>bridge_length</code>만큼 시간이 소요되므로 <code>맨 마지막 트럭이 다리 위로 올라갈 때 까지 걸린 시간 + bridge_length</code>가 답이 된다.</p>
<h3 id="시간-복잡도">시간 복잡도</h3>
<p><code>O(N)</code>
<code>N : answer - bridge_length</code></p>
<h3 id="문제-풀-때-참고-사이트">문제 풀 때 참고 사이트</h3>
]]></description>
        </item>
        <item>
            <title><![CDATA[[알고리즘] Binary Search]]></title>
            <link>https://velog.io/@emily0_0/%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98-Binary-Search</link>
            <guid>https://velog.io/@emily0_0/%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98-Binary-Search</guid>
            <pubDate>Mon, 26 Oct 2020 11:01:03 GMT</pubDate>
            <description><![CDATA[<h3 id="abstract">Abstract</h3>
<ul>
<li>탐색 범위를 두 부분으로 분할하면서 찾는 방식.</li>
<li>처음부터 끝까지 돌면서 탐색하는 것보다 훨씬 빠르다.</li>
</ul>
<h3 id="processascending">Process(Ascending)</h3>
<blockquote>
<ol>
<li>정렬을 한다. <code>오름차순으로 정렬한다고 가정한다.</code></li>
<li>mid 값을 정한다. <code>mid = (left+right)/2</code></li>
<li>mid 와 찾고자 하는 값을 비교한다.</li>
<li>구할 값이 mid보다 Index가 높으면 <code>left = mid + 1</code>
 구할 값이 mid보다 Index가 낮으면 <code>right = mid - 1</code></li>
<li><strong>left가 right보다 커질 때 까지 반복</strong>한다.</li>
</ol>
</blockquote>
<h3 id="c-codeascending">C++ Code(Ascending)</h3>
<pre><code class="language-c">int binarySearch(vector&lt;int&gt; arr, int target){
  int low = 0;
  int high = arr[arr.size()-1];

  while(low &lt;= high){
    int mid = (low+high)/2;

    if(arr[mid] == target)
      return mid;

    if(arr[mid] &gt; target)
      high = mid - 1;
    else 
      low = mid + 1;
  }
  return high;
}</code></pre>
<h3 id="gif로-이해하는-binary-search">GIF로 이해하는 Binary Search</h3>
<p><img src="https://images.velog.io/images/emily0_0/post/789a9b80-9c07-4056-af62-8aa4d4529800/bePceUMnSG-binary_search_gif.gif" alt=""></p>
<h3 id="시간복잡도">시간복잡도</h3>
<p><code>O(log₂n)</code></p>
<h3 id="공간복잡도">공간복잡도</h3>
<p><code>O(n)</code></p>
<h3 id="참고-사이트">참고 사이트</h3>
<p><a href="https://gyoogle.dev/blog/algorithm/Binary%20Search.html">Binary Search 설명</a>
<a href="https://ko.wikipedia.org/wiki/%EC%9D%B4%EC%A7%84_%EA%B2%80%EC%83%89_%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98">Binary Search Code</a>
<a href="https://brilliant.org/wiki/binary-search/">Binary Search Image</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[알고리즘] Heap Sort]]></title>
            <link>https://velog.io/@emily0_0/%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98-Heap-Sort</link>
            <guid>https://velog.io/@emily0_0/%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98-Heap-Sort</guid>
            <pubDate>Mon, 26 Oct 2020 10:25:16 GMT</pubDate>
            <description><![CDATA[<h3 id="abstract">Abstract</h3>
<ul>
<li>완전 이진 트리(Complete binary tree)를 기본으로 하는 힙(Heap) 자료구조를 기반으로 한 정렬 방식</li>
</ul>
<blockquote>
<p><strong>Complete binary tree</strong>
삽입 시 왼쪽부터 차례대로 추가하는 <a href="https://ratsgo.github.io/data%20structure&amp;algorithm/2017/10/21/tree/">이진 트리</a></p>
</blockquote>
<blockquote>
<p><strong>Heap</strong>
큰 키(우선 순위)에 자주 엑세스 하거나 키(우선 순위) 중심으로 정렬된 시퀀스를 활용해야 할 때 유용한 자료구조이다.</p>
</blockquote>
<h3 id="heap-property">Heap property</h3>
<h4 id="heap-order-property">heap order property</h4>
<p>각 노드의 값은 자신의 자식노드가 가진 값보다 크거나 같다. <code>Max heap</code>
각 노드의 값은 자신의 자식노드가 가진 값보다 작거나 같다. <code>Min heap</code></p>
<h4 id="heap-shape-property">heap shape property</h4>
<p>완전 이진 트리 모양으로, 마지막 레벨의 모든 노드는 왼쪽에 쏠려 있다.</p>
<h3 id="processascending">Process(Ascending)</h3>
<blockquote>
<ol>
<li>주어진 원소들로 최대 힙을 구성한다.</li>
<li>최대 힙의 루트노드와 말단노드를 교환하고 말단노드를 꺼낸다.
 루트노드 <code>현재 배열의 첫번째 요소 ➡ 최댓값</code>
 말단노드 <code>현재 배열의 마지막 요소</code>
 <img src="https://images.velog.io/images/emily0_0/post/6caf598a-81cb-4aea-9abc-7b721c7aba5d/image.png" alt=""></li>
<li>새 루트노드에 대해 최대 힙을 구성한다.
<img src="https://images.velog.io/images/emily0_0/post/b971f66a-b36d-4787-9c70-249a718a0e6d/image.png" alt=""></li>
<li>원소의 개수만큼 2번과 3번을 반복 수행한다.</li>
</ol>
</blockquote>
<h3 id="c-codeascending">C++ Code(Ascending)</h3>
<h4 id="heapsort">HeapSort</h4>
<pre><code class="language-c">void heapSort(int arr[], int arrSize){
  int n = arrSize;

  // Build Max Heap : 1단계
  for(int i=n/2-1; i&gt;=0; i--){
    heapify(arr, n, i);
  }

  // 힙 크기를 줄이고 자리 이동 : 2~4단계
  for (int i=n-1; i&gt;0; i--){
    swap(arr[0], arr[i]);
    heapify(arr, i, 0);
  }
}</code></pre>
<h4 id="heapify">Heapify</h4>
<blockquote>
<p>주어진 자료구조에서 힙 성질을 만족하도록 하는 연산</p>
</blockquote>
<pre><code class="language-c">void heapify(int arr[], int n, int i){
  int p = i;
  int l = i*2 + 1;
  int r = i*2 + 2;

  // 왼쪽 자식 노드
  if (l &lt; n &amp;&amp; arr[p] &lt; arr[l]){
    p = l;
  }
  // 오른쪽 자식 노드
  if (r &lt; n &amp;&amp; arr[p] &lt; arr[r]){
    p = r;
  }

  // 부모노드 &lt; 자식노드
  if(i != p){
    swap(arr[p], arr[i]);
    heapify(arr, n, p);
  }
}</code></pre>
<h3 id="gif로-이해하는-heap-sort">GIF로 이해하는 Heap Sort</h3>
<p><img src="https://images.velog.io/images/emily0_0/post/c12940ac-be54-4524-a6f4-56d5f299aa02/Heap_sort_example.gif" alt=""></p>
<h3 id="시간복잡도">시간복잡도</h3>
<ul>
<li><p>Heapify : <code>log₂n</code>
말단 노드(최댓값)이 루트 노드에 올라오기까지 트리의 높이만큼 자리를 이동해야 하므로 <code>log₂n</code> 만큼 이동해야 한다.</p>
</li>
<li><p>Heapify를 해야 하는 노드 개수 : <code>n</code></p>
</li>
</ul>
<p>따라서 시간복잡도는 <code>Heapify * Heapify를 해야 하는 노드 개수 = nlog₂n</code>가 된다.</p>
<blockquote>
<p>Best case : <code>O(nlog₂n)</code>
Worst case : <code>O(nlog₂n)</code>
Average case : <code>O(nlog₂n)</code></p>
</blockquote>
<h3 id="공간복잡도">공간복잡도</h3>
<p><code>O(n)</code></p>
<h3 id="장점">장점</h3>
<ul>
<li>가장 크거나 작은 값을 구할 때 최소 힙, 최대 힙의 루트 값이기 때문에 한 번의 힙 구성으로 값을 구할 수 있다.</li>
<li>최대 k만큼 떨어진 요소들을 정렬할 때, 삽입 정렬보다 더욱 개선된 결과를 얻을 수 있다.</li>
</ul>
<h3 id="단점">단점</h3>
<ul>
<li><strong>불안정 정렬</strong>(Unstable Sort)이다.</li>
</ul>
<h3 id="참고-사이트">참고 사이트</h3>
<p><a href="https://ratsgo.github.io/data%20structure&amp;algorithm/2017/09/27/heapsort/#">Heap Sort1</a>
<a href="https://gyoogle.dev/blog/algorithm/Heap%20Sort.html">Heap Sort2</a>
<a href="https://velog.io/@kjh107704/Heap">최대 힙과 최소 힙</a>
<a href="https://commons.wikimedia.org/wiki/File:Heap_sort_example.gif">Heap Sort Image</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[알고리즘] Merge Sort]]></title>
            <link>https://velog.io/@emily0_0/%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98-Merge-Sort</link>
            <guid>https://velog.io/@emily0_0/%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98-Merge-Sort</guid>
            <pubDate>Mon, 26 Oct 2020 04:48:10 GMT</pubDate>
            <description><![CDATA[<h3 id="abstract">Abstract</h3>
<ul>
<li>Merge Sort는 <strong>분할 정복</strong>(Divide and Conquer) 방법을 통해 주어진 배열을 정렬한다.</li>
</ul>
<blockquote>
<p>*<em>Divide and Conquer *</em>
문제를 작은 2개의 문제로 분리하고 각각을 해결한 다음, 결과를 모아서 원래의 문제를 해결하는 전략</p>
</blockquote>
<h3 id="processascending">Process(Ascending)</h3>
<blockquote>
<ol>
<li>영역을 두개의 <span style="color:teal"><strong>sub problem</strong></span>으로 쪼갠다. 이때, 쪼갠 영역의 크기는 최대한 같게 한다. ➡ <strong>MergeSort</strong></li>
<li>쪼갠 영역을 합병하면서 정렬한다. ➡ <strong>Merge</strong></li>
</ol>
</blockquote>
<h3 id="c-codeascending">C++ Code(Ascending)</h3>
<h4 id="mergesort">MergeSort</h4>
<pre><code class="language-c">void mergeSort(int arr[], int left, int right){
  if(left &lt; right){
    int mid = (left+right) / 2;

    mergeSort(arr, left, mid);
    mergeSort(arr, mid+1, right);
    merge(arr, left, mid, right);
  }
}</code></pre>
<h4 id="merge">Merge</h4>
<pre><code class="language-c">void merge(int arr[], int left, int mid, int right){
  int ll = mid-left+1; // left array length
  int rl = right-mid; // right array length
  int L[ll], R[rl];

  for(int i=0; i&lt;ll; i++){
    L[i] = arr[left+i];
  } 
  for(int j=0; j&lt;rl; j++){
    R[j] = arr[mid+1+j];
  }

  int i=0, j=0, k=left;
  while(i&lt;ll &amp;&amp; j&lt;rl){
    if(L[i] &lt;= R[j]){
      arr[k] = L[i++];
    }
    else{
      arr[k] = R[j++];
    }
    k++;
  }

  while(i&lt;ll){
    arr[k++] = L[i++];
  }
  while(j&lt;rl){
    arr[k++] = R[j++];
  }
}</code></pre>
<h3 id="gif로-이해하는-merge-sort">GIF로 이해하는 Merge Sort</h3>
<p><img src="https://images.velog.io/images/emily0_0/post/d35d6b3f-e7d9-44e7-934f-fb9856de69e2/merge-sort.gif" alt=""></p>
<h3 id="시간복잡도">시간복잡도</h3>
<ul>
<li><p>비교횟수 : <code>log₂n</code>
레코드의 개수 n이 <strong>2의 거듭제곱</strong>이라고 가정했을 때, <code>n = 2^k</code>라고 표현할 수 있다.
<code>n = 2^3</code>의 경우, <code>2^3 -&gt; 2^2 -&gt; 2^1 -&gt; 2^0</code> 순으로 줄어들어 순환 호출의 깊이가 3이다.
이를 일반화 하면, <code>n = 2^k</code> 이므로 호출의 깊이는 <code>k</code>이다.
이 때, <code>k = log₂n</code> 이므로 비교횟수는 <code>log₂n</code> 이다.</p>
</li>
<li><p>각 순환 호출 단계의 비교 연산 : <code>n</code>
각 순환 호출에서 전체 리스트의 거의 모든 레코드를 비교해야 하므로 <strong>n번의 비교가 발생</strong>한다.</p>
</li>
</ul>
<p>따라서 시간복잡도는 <code>순환 호출의 깊이 * 각 순환 호출 단계 비교 연산 = nlog₂n</code>가 된다.</p>
<blockquote>
<p><strong>Best case</strong> : <code>O(nlog₂n)</code>
<strong>Worst case</strong> : <code>O(nlog₂n)</code>
<strong>Average case</strong> : <code>O(nlog₂n)</code></p>
</blockquote>
<h3 id="공간복잡도">공간복잡도</h3>
<p><code>O(n)</code></p>
<h3 id="장점">장점</h3>
<ul>
<li>안정 정렬</li>
<li>빠르다</li>
</ul>
<h3 id="단점">단점</h3>
<ul>
<li>제자리 정렬을 하지 않고 새로운 메모리에 정렬 후에 원래 리스트에 결과를 저장한다.</li>
<li>실제 사용시 <a href="https://velog.io/@emily0_0/%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98-Quick-Sort">퀵 소트</a>와 힙 소트보다 느린 경우가 많다.</li>
</ul>
<h3 id="참고-사이트">참고 사이트</h3>
<p><a href="https://gyoogle.dev/blog/algorithm/Merge%20Sort.html">Merge Sort1</a>
<a href="https://codepumpkin.com/merge-sort-sorting-algorithm/">Merge Sort2</a>
<a href="http://blog.naver.com/npng92/220427871122">Merge Sort3</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[프로그래머스] 스택/큐 - 기능개발]]></title>
            <link>https://velog.io/@emily0_0/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-%EC%8A%A4%ED%83%9D%ED%81%90-%EA%B8%B0%EB%8A%A5%EA%B0%9C%EB%B0%9C</link>
            <guid>https://velog.io/@emily0_0/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-%EC%8A%A4%ED%83%9D%ED%81%90-%EA%B8%B0%EB%8A%A5%EA%B0%9C%EB%B0%9C</guid>
            <pubDate>Mon, 26 Oct 2020 02:17:48 GMT</pubDate>
            <description><![CDATA[<p><a href="https://programmers.co.kr/learn/courses/30/lessons/42586">프로그래머스 - 기능개발</a></p>
<h3 id="문제-설명">문제 설명</h3>
<blockquote>
<p>기능을 배포할 때, 각 배포마다 몇 개의 기능이 배포되는지 <span style = "color : teal">return</span>하기.</p>
</blockquote>
<h3 id="제한사항">제한사항</h3>
<blockquote>
<p>상대적으로 뒤에 있는 기능이 먼저 개발되면, 앞에 있는 기능이 배포될 때 함께 배포된다.
<strong>작업의 개수</strong>(progresses, speeds배열의 길이)는 <strong>100개 이하</strong>이다.
작업 진도는 <strong>100 미만의 자연수</strong>이다.
작업 속도는 <strong>100 이하의 자연수</strong>이다.
배포는 <strong>하루에 한 번</strong>만 할 수 있으며, 하루의 끝에 이루어진다고 가정한다.</p>
</blockquote>
<h3 id="문제풀이">문제풀이</h3>
<blockquote>
<ol>
<li>각 작업을 배포하기 위해 걸리는 시간을 계산한다.</li>
<li><strong>가장 앞선 기능</strong>보다 <strong>더 늦게 개발되는 기능</strong>을 찾는다.</li>
<li><strong>가장 앞선 기능</strong>부터 <strong>더 늦게 개발되는 기능</strong> 전까지의 기능 개수를 <strong>answer</strong>에 넣어준다. ➡ <em>배포</em></li>
<li><strong>더 늦게 개발되는 기능</strong>을 <strong>가장 앞선 기능</strong>으로 선택하여 새로운 배포를 한다.</li>
</ol>
</blockquote>
<h3 id="코드">코드</h3>
<pre><code class="language-c">#include &lt;string&gt;
#include &lt;vector&gt;
#include &lt;math.h&gt;

using namespace std;

vector&lt;int&gt; solution(vector&lt;int&gt; progresses, vector&lt;int&gt; speeds) {
    vector&lt;int&gt; answer;
    int maxDay = 0;
    int maxDaysIdx = 0;
    int day;
    int restTask;

    for(int i=0; i&lt;progresses.size(); i++){
        restTask = 100 - progresses[i];
        day = floor(restTask / speeds[i]);

        if(restTask % speeds[i] &gt; 0) day ++;

        if(maxDay &lt; day){
            if(i!=0){
                answer.push_back(i - maxDaysIdx);
                maxDaysIdx = i;
            }
            maxDay = day;
        }
    }
    answer.push_back(progresses.size() - maxDaysIdx);
    return answer;
}</code></pre>
<h3 id="시간-복잡도">시간 복잡도</h3>
<p>Θ(N)
N : 작업 개수</p>
<h3 id="문제-풀-때-참고-사이트">문제 풀 때 참고 사이트</h3>
]]></description>
        </item>
        <item>
            <title><![CDATA[[알고리즘] Quick Sort]]></title>
            <link>https://velog.io/@emily0_0/%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98-Quick-Sort</link>
            <guid>https://velog.io/@emily0_0/%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98-Quick-Sort</guid>
            <pubDate>Sat, 24 Oct 2020 15:30:41 GMT</pubDate>
            <description><![CDATA[<h3 id="abstract">Abstract</h3>
<ul>
<li>Quick Sort는 <strong>분할 정복</strong>(Divide and Conquer) 방법을 통해 주어진 배열을 정렬한다.</li>
<li>다른 원소와의 비교만으로 정렬을 수행하는 <strong>비교 정렬</strong>이다.</li>
<li>배열을 <strong>비균등하게 분할</strong>한다.</li>
</ul>
<blockquote>
<p>*<em>Divide and Conquer *</em>
문제를 작은 2개의 문제로 분리하고 각각을 해결한 다음, 결과를 모아서 원래의 문제를 해결하는 전략</p>
</blockquote>
<h3 id="processascending">Process(Ascending)</h3>
<blockquote>
<ol>
<li>배열에서 하나의 원소를 고른다. ➡ <strong>피벗(pivot)</strong></li>
<li>피벗 앞에는 피벗 보다 작은 모든 원소들이 오고, 뒤에는 큰 원소들이 오도록 <strong>피벗을 기준으로 배열을 둘로 나눈다</strong>.
분할을 마친 뒤에 피벗은 더 이상 움직이지 않는다.</li>
<li>분할된 두 개의 작은 배열에 대해 <strong>재귀적으로 이 과정을 반복</strong>한다.
재귀 호출이 한 번 진행될 때마다 최소한 하나의 원소는 최종 위치가 정해지므로, 알고리즘이 반드시 끝난다는 것을 보장할 수 있다.</li>
</ol>
</blockquote>
<h3 id="c-codeascending">C++ Code(Ascending)</h3>
<p>Quick Sort는  <span style="color:teal"> Divide</span>와 <span style="color:teal">Conquer</span>로 이루어져 있다.</p>
<h4 id="정복-conquer">정복 (Conquer)</h4>
<blockquote>
<p>부분 배열을 정렬한다.
순환 호출을 이용하여 다시 분할 정복 방법을 적용한다.</p>
</blockquote>
<pre><code class="language-c">void quickSort(int arr[], int left, int right){
  if(left &gt;= right) return;

  int pivot = partition(arr, left, right); // 분할

  // pivot을 제외한 2개의 부분 배열을 대상으로 순환 호출
  quickSort(arr, left, pivot-1);  // left Conquer
  quickSort(arr, pivot+1, right); // right Conquer
}</code></pre>
<h4 id="분할-divide">분할 (Divide)</h4>
<blockquote>
<p>입력 배열을 <strong>피벗 기준</strong>으로 <strong>비균등하게</strong> 2개의 부분 배열로 <strong>분할</strong>한다.
피벗을 중심으로 <strong>왼쪽은 작은 요소</strong>들, <strong>오른쪽은 큰 요소</strong>들이 오게 한다.</p>
</blockquote>
<pre><code class="language-c">int partition(int arr[], int left, int right){
  int mid = (left + right) / 2;
  swap(arr[left], arr[mid]);

  int pivot = arr[left]; //가장 왼쪽 값을 pivot으로 설정
  int i = left, j = right;

  while(i&lt;j){
    while(pivot &lt; arr[j]){ //오른쪽부터 작은 값을 찾는다.
      j--;
    }
    while(i&lt;j &amp;&amp; pivot &gt;= arr[i]){ //왼쪽부터 큰 값을 찾는다.
      i++;
    }
    swap(arr[i], arr[j]); //교환
  }

  arr[left] = arr[i];
  arr[i] = pivot;
  return i;
}</code></pre>
<h3 id="quick-sort-개선">Quick Sort 개선</h3>
<p><span style="color:teal"><strong>partition()</strong></span>에서 피벗 값이 최소나 최대값으로 지정되어 <strong>파티션이 나누어지지 않을 때</strong>, <strong>O(n^2)</strong>에 대한 시간복잡도를 가진다.
즉, <strong>배열이</strong> 오름차순 또는 내림차순으로 <strong>정렬되어 있는 경우</strong>에 <strong>O(n^2)</strong>를 갖게 된다.
배열에서 가장 앞에 있는 값과 중간 값을 교환한다면, 확률적으로 시간복잡도를 <strong>O(nlog₂n)</strong>으로 개선할 수 있다.
하지만 이 방법으로도 Worst case의 시간복잡도를 O(nlog₂n)로 만들 수 없다.</p>
<h3 id="gif로-이해하는-quick-sort">GIF로 이해하는 Quick Sort</h3>
<p><img src="https://images.velog.io/images/emily0_0/post/b06a5edc-3690-4c79-9ee6-a850c92fb1e0/quick-sort-001.gif" alt=""></p>
<h3 id="시간복잡도">시간복잡도</h3>
<h4 id="best-case--tn--onlog₂n">Best case : T(n) = O(nlog₂n)</h4>
<ul>
<li><p>비교횟수 : <code>log₂n</code>
레코드의 개수 n이 <strong>2의 거듭제곱</strong>이라고 가정했을 때, <code>n = 2^k</code>라고 표현할 수 있다.
<code>n = 2^3</code>의 경우, <code>2^3 -&gt; 2^2 -&gt; 2^1 -&gt; 2^0</code> 순으로 줄어들어 순환 호출의 깊이가 3이다.
<img src="https://images.velog.io/images/emily0_0/post/e8faf6de-fadb-4717-af9c-fd2b1e08ecf3/quick-sort-002.png" alt="">
이를 일반화 하면, <code>n = 2^k</code> 이므로 호출의 깊이는 <code>k</code>이다.
이 때, <code>k = log₂n</code> 이므로 비교횟수는 <code>log₂n</code> 이다.</p>
</li>
<li><p>각 순환 호출 단계의 비교 연산 : <code>n</code>
각 순환 호출에서 전체 리스트의 거의 모든 레코드를 비교해야 하므로 <strong>평균 n번 정도의 비교가 발생</strong>한다.</p>
</li>
</ul>
<p>따라서 <strong>Best case</strong>의 시간복잡도는 <code>순환 호출의 깊이 * 각 순환 호출 단계 비교 연산 = nlog₂n</code>가 된다.</p>
<h4 id="worst-case--tn--on2">Worst case : T(n) = O(n^2)</h4>
<p>최악의 경우 : 배열이 이미 정렬되어 있는 경우</p>
<ul>
<li><p>비교횟수 : <code>n</code>
<img src="https://images.velog.io/images/emily0_0/post/b94c455d-a853-4efd-afcd-218e1044167f/quick-sort-003.png" alt="">
레코드의 개수 n이 <strong>2의 거듭제곱</strong>이라고 가정했을 때, <code>n = 2^k</code>라고 표현할 수 있다. 이 때, 순환 호출의 깊이는 <code>n</code>이다.</p>
</li>
<li><p>각 순환 호출 단계의 비교 연산 : <code>n</code>
각 순환 호출에서는 전체 리스트의 대부분 레코드를 비교해야 하므로 <strong>평균 n번</strong> 비교한다.</p>
</li>
</ul>
<p>따라서 <strong>Worst case</strong>의 시간복잡도는 <code>순환 호출의 깊이 * 각 순환 호출 단계 비교 연산 = n^2</code>가 된다.</p>
<h4 id="average-case--tn--onlog₂n">Average case : T(n) = O(nlog₂n)</h4>
<h3 id="공간복잡도">공간복잡도</h3>
<p>주어진 배열 안에서 교환을 통해 정렬이 수행되므로 <strong>O(n)</strong>.</p>
<h3 id="장점">장점</h3>
<ul>
<li>불필요한 데이터의 이동을 줄이고 먼 거리의 데이터를 교환한다.</li>
<li>한 번 결정된 피벗들이 추후 연산에서 제외된다.</li>
<li>정렬하려는 배열 안에서 교환하는 방식으로 다른 메모리 공간을 필요로 하지 않는다. <code>제자리 정렬</code></li>
</ul>
<h3 id="단점">단점</h3>
<ul>
<li><strong>불안정 정렬</strong>(Unstable Sort)이다.</li>
<li>정렬된 배열에서는 Quick Sort의 불균형 분할에 의해 수행시간이 많이 걸린다.</li>
</ul>
<h3 id="참고-사이트">참고 사이트</h3>
<p><a href="https://gyoogle.dev/blog/algorithm/Quick%20Sort.html">Quick Sort</a>
<a href="https://godgod732.tistory.com/10">안정 정렬과 불안정 정렬</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[알고리즘] Selection Sort]]></title>
            <link>https://velog.io/@emily0_0/%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98-Selection-Sort</link>
            <guid>https://velog.io/@emily0_0/%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98-Selection-Sort</guid>
            <pubDate>Sat, 24 Oct 2020 10:03:42 GMT</pubDate>
            <description><![CDATA[<h3 id="abstract">Abstract</h3>
<p>Selection Sort는 <code>해당 순서에 원소를 넣을 위치는 이미 정해져 있고, 어떤 원소를 넣을지 선택하는 알고리즘</code> 이다.</p>
<h3 id="processascending">Process(Ascending)</h3>
<blockquote>
<ol>
<li>주어진 배열 중에 최소값을 찾는다.</li>
<li>그 값을 맨 앞에 위치한 값과 교체한다.</li>
<li>맨 처음 위치를 제외한 나머지 배열을 같은 방법으로 교체한다.</li>
</ol>
</blockquote>
<h3 id="c-codeascending">C++ Code(Ascending)</h3>
<pre><code class="language-c">#include &lt;iostream&gt;
#include &lt;vector&gt;
using namespace std;

void SelectionSort(vector&lt;int&gt; arr){
  int indexMin, temp = 0;
  for(int i=0; i&lt;arr.size()-1; i++){    // 1
    indexMin = i;
    for (int j=i+1; j&lt;arr.size(); j++){ // 2
      if(arr[j] &lt; arr[indexMin]){       // 3
        indexMin = j;
      }
    }
    swap(arr[indexMin], arr[i]);        // 4
  }
}</code></pre>
<h3 id="주석-설명">주석 설명</h3>
<blockquote>
<ol>
<li>범위에서 가장 작은 값이 들어갈 위치를 선택한다.</li>
<li>i+1번째 인덱스에서부터 끝까지 값을 확인한다.</li>
<li>범위에서 가장 작은 값을 찾아서 인덱스를 <strong>indexMin</strong>에 저장한다.</li>
<li>indexMin 위치의 값과 가장 작은 값이 들어갈 위치의 값을 교환한다.</li>
</ol>
</blockquote>
<h3 id="gif로-이해하는-selection-sort">GIF로 이해하는 Selection Sort</h3>
<p><img src="https://images.velog.io/images/emily0_0/post/2f941bf0-9f39-489a-b22e-966f7b6d8d91/selection-sort-001.gif" alt=""></p>
<h3 id="시간복잡도">시간복잡도</h3>
<p><code>(n-1) + (n-2) + (n-3) + ... + 2 + 1 ➡ n(n-1)/2</code> 이므로 시간복잡도는 <strong>O(n^2)</strong>.
정렬 여부에 상관없이 비교를 하기 때문에 최선, 평균, 최악의 경우 모두 <strong>O(n^2)</strong>.</p>
<h3 id="공간복잡도">공간복잡도</h3>
<p>주어진 배열 안에서 교환을 통해 정렬이 수행되므로 <strong>O(n)</strong>.</p>
<h3 id="장점">장점</h3>
<ul>
<li>구현이 매우 간단하고 소스코드가 직관적이다.</li>
<li>정렬하려는 배열 안에서 교환하는 <strong>제자리 정렬</strong>(in-place sorting) 방식이므로 다른 메모리 공간이 필요하지 않다.</li>
<li>정렬을 위한 비교횟수는 많지만, <a href="https://velog.io/@emily0_0/%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98-Bubble-Sort">Bubble Sort</a> 에 비해 실제로 교환하는 횟수는 적기 때문에 많은 교환이 일어나야 하는 자료상태에서 비교적 효율적이다.</li>
</ul>
<h3 id="단점">단점</h3>
<ul>
<li>시간복잡도가 최악, 최선, 평균 모두 <strong>O(n^2)</strong>로 비효율적이다.</li>
<li>동일한 값에 대해 기존의 순서가 유지되지 않는 <strong>불안정 정렬</strong>(Unstable Sort) 입니다.</li>
</ul>
<h3 id="참고-사이트">참고 사이트</h3>
<p><a href="https://github.com/GimunLee/tech-refrigerator/blob/master/Algorithm/%EC%84%A0%ED%83%9D%20%EC%A0%95%EB%A0%AC%20(Selection%20Sort).md#%EC%84%A0%ED%83%9D-%EC%A0%95%EB%A0%AC-selection-sort">선택 정렬</a>
<a href="https://godgod732.tistory.com/10">안정 정렬과 불안정 정렬</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[알고리즘] Bubble Sort]]></title>
            <link>https://velog.io/@emily0_0/%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98-Bubble-Sort</link>
            <guid>https://velog.io/@emily0_0/%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98-Bubble-Sort</guid>
            <pubDate>Sat, 24 Oct 2020 09:26:15 GMT</pubDate>
            <description><![CDATA[<h3 id="abstract">Abstract</h3>
<p>Bubble Sort는 <code>서로 인접한 두 원소의 대소를 비교하고, 조건에 맞지 않다면 자리를 교환하며 정렬하는 알고리즘</code> 이다.</p>
<p>정렬 과정이 거품이 수면으로 올라오는 듯한 모습을 보이기 때문에 <strong>Bubble</strong>라는 이름이 붙었다.</p>
<h3 id="processascending">Process(Ascending)</h3>
<blockquote>
<ol>
<li>1회전에 첫 번째 원소와 두 번째 원소를, 두 번째 원소와 세 번째 원소를, 세 번째 원소와 네 번째 원소를, ... 이런 식으로 (마지막-1)번째 원소와 마지막 원소를 비교하여 조건에 맞지 않는다면 서로 교환한다.</li>
</ol>
</blockquote>
<blockquote>
<ol start="2">
<li>1회전을 수행하고 나면 가장 큰 원소가 맨 뒤로 이동하므로 2회전에서는 맨 끝에 있는 원소는 정렬에서 제외되고, 2회전을 수행하고 나면 끝에서 두 번째 원소까지는 정렬에서 제외된다.
이렇게 정렬을 1회전 수행할 때마다 정렬에서 제외되는 데이터가 하나씩 늘어난다.</li>
</ol>
</blockquote>
<h3 id="c-codeascending">C++ Code(Ascending)</h3>
<pre><code class="language-c">#include &lt;iostream&gt;
#include &lt;vector&gt;
using namespace std;

void BubbleSort(vector&lt;int&gt; arr){
  int temp = 0;
  for(int i=0; i&lt;arr.size(); i++){     // 1
    for(int j=1; j&lt;arr.size()-i; j++){ // 2
      if(arr[j-1] &gt; arr[j]){            // 3
        swap(arr[j-1], arr[j]);
      }
    }
  }
}</code></pre>
<h3 id="주석-설명">주석 설명</h3>
<blockquote>
<ol>
<li>제외될 원소의 개수를 의미한다. 1회전이 끝난 후, 배열의 마지막 위치에는 가장 큰 원소가 위치하기 때문에 하나씩 증가시켜준다.</li>
<li>원소를 비교할 인덱스를 뽑는 반복문이다. j는 현재 원소를 가리키고, j-1은 이전 원소를 가리킨다.</li>
<li>현재 가리키고 있는 두 원소의 대소를 비교한다. 오름차순으로 정렬하기 위해 현재 원소 보다 이전 원소가 더 크다면 자리를 교환한다.</li>
</ol>
</blockquote>
<h3 id="gif로-이해하는-bubble-sort">GIF로 이해하는 Bubble Sort</h3>
<p><img src="https://images.velog.io/images/emily0_0/post/07c89f25-97e1-4370-9a87-168d5e4fea0c/bubble-sort-001.gif" alt=""></p>
<h3 id="시간복잡도">시간복잡도</h3>
<p><code>(n-1) + (n-2) + (n-3) + ... + 2 + 1 ➡ n(n-1)/2</code> 이므로 시간복잡도는 <strong>O(n^2)</strong>.
정렬 여부에 상관없이 비교를 하기 때문에 최선, 평균, 최악의 경우 모두 <strong>O(n^2)</strong>.</p>
<h3 id="공간복잡도">공간복잡도</h3>
<p>주어진 배열 안에서 교환을 통해 정렬이 수행되므로 <strong>O(n)</strong>.</p>
<h3 id="장점">장점</h3>
<ul>
<li>구현이 매우 간단하고 소스코드가 직관적이다.</li>
<li>정렬하려는 배열 안에서 교환하는 <strong>제자리 정렬</strong>(in-place sorting) 방식이므로 다른 메모리 공간이 필요하지 않다.</li>
<li>동일한 값에 대해 기존의 순서가 유지되는 <strong>안정정렬</strong>(stable sort) 이다.</li>
</ul>
<h3 id="단점">단점</h3>
<ul>
<li>시간복잡도가 최악, 최선, 평균 모두 O(n^2)로 비효율적이다.</li>
<li>정렬되지 않은 원소가 정렬되기 위해 swap이 많이 일어난다.</li>
</ul>
<h3 id="참고-사이트">참고 사이트</h3>
<p><a href="https://github.com/GimunLee/tech-refrigerator/blob/master/Algorithm/%EA%B1%B0%ED%92%88%20%EC%A0%95%EB%A0%AC%20(Bubble%20Sort).md">Bubble Sort</a>
<a href="https://godgod732.tistory.com/10">안정 정렬과 불안정 정렬</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[프로그래머스] 해시 - 베스트앨범]]></title>
            <link>https://velog.io/@emily0_0/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-%ED%95%B4%EC%8B%9C-%EB%B2%A0%EC%8A%A4%ED%8A%B8%EC%95%A8%EB%B2%94</link>
            <guid>https://velog.io/@emily0_0/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-%ED%95%B4%EC%8B%9C-%EB%B2%A0%EC%8A%A4%ED%8A%B8%EC%95%A8%EB%B2%94</guid>
            <pubDate>Sat, 24 Oct 2020 03:40:27 GMT</pubDate>
            <description><![CDATA[<p><img src="https://images.velog.io/images/emily0_0/post/93092ee2-cf09-4255-80b4-2fe85ef2babf/_.jpeg" alt=""></p>
<p><a href="https://programmers.co.kr/learn/courses/30/lessons/42579#">프로그래머스 - 베스트앨범</a></p>
<h3 id="문제-설명">문제 설명</h3>
<blockquote>
<p>스트리밍 사이트에서 장르 별로 가장 많이 재생된 노래 <span style = "color : blue">두 개씩 </span> 모아 베스트 앨범 출시하기</p>
</blockquote>
<h3 id="제한사항">제한사항</h3>
<blockquote>
<p>속한 노래가 <strong>많이 재생된 장르부터 수록</strong>한다.
장르 내에서 <strong>많이 재생된 순서로 노래를 수록</strong>한다.
장르 내에서 재생 횟수가 같은 노래 중에서는 <strong>고유 번호가 낮은 노래부터 수록</strong>한다.
genres와 plays의 길이는 같으며, 이는 <strong>1 이상 10,000 이하</strong>이다.
고유번호는 index이다.
장르 종류는 <strong>100개 미만</strong>이다.
장르에 속한 곡이 하나라면, 하나의 곡만 선택한다.
모든 장르는 재생된 횟수가 다르다.</p>
</blockquote>
<h3 id="문제풀이">문제풀이</h3>
<blockquote>
<p>장르 별 총 재생 횟수가 많은 것부터 적은 순서로 정렬해서 이 순서로 노래를 수록한다.
같은 장르 속 노래들을 재생 횟수가 많은 것부터 적은 순서로 정렬해서 이 순서로 노래를 수록한다.
재생 횟수가 같다면 인덱스가 작은 것부터 큰 순서로 정렬한다.
만약 장르 속 노래가 하나라면 하나만 선택한다.
두개 이상이면 가장 재생이 많이 된 노래 2개를 선택한다.</p>
</blockquote>
<h3 id="코드">코드</h3>
<pre><code class="language-c">#include &lt;string&gt;
#include &lt;vector&gt;
#include &lt;algorithm&gt;
#include &lt;unordered_map&gt;

using namespace std;

bool cmp_genres(const pair&lt;string,int&gt;&amp; a, const pair&lt;string,int&gt;&amp; b) {
    return a.second &gt; b.second;
}

bool cmp_plays(const pair&lt;int,int&gt;&amp; a, const pair&lt;int,int&gt;&amp; b) {
    if(a.second == b.second)
        return a.first &lt; b.first;
    return a.second &gt; b.second;
}

vector&lt;int&gt; solution(vector&lt;string&gt; genres, vector&lt;int&gt; plays) {
    vector&lt;int&gt; answer;
    unordered_map&lt;string, vector&lt;pair&lt;int, int&gt;&gt;&gt; gp_map;
    unordered_map&lt;string, int&gt; gp_sum;

    for(int i=0; i&lt;genres.size(); i++){
        gp_sum[genres[i]] +=plays[i];
        gp_map[genres[i]].push_back(pair(i, plays[i]));
    }

    vector&lt;pair&lt;string,int&gt;&gt; gp_sumV(gp_sum.begin(), gp_sum.end());
    sort(gp_sumV.begin(), gp_sumV.end(), cmp_genres);

    for(int i=0; i&lt;gp_sumV.size(); i++){
        string genre = gp_sumV[i].first;

        if(gp_map[genre].size() == 1){
            answer.push_back(gp_map[genre][0].first);
        }
        else{
            sort(gp_map[genre].begin(), gp_map[genre].end(), cmp_plays);
            answer.push_back(gp_map[genre][0].first);
            answer.push_back(gp_map[genre][1].first);
        }
    }

    return answer;
}</code></pre>
<h3 id="시간-복잡도">시간 복잡도</h3>
<p>O(N*MlogM)
N : 장르 개수
M : 장르 속 노래 최대 개수</p>
<h3 id="문제-풀-때-참고-사이트">문제 풀 때 참고 사이트</h3>
<p><a href="https://unluckyjung.github.io/cpp/2020/05/07/Sort_map_by_value/">C++ Map을 value 기준으로 정렬하기</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[프로그래머스] 해시 - 위장]]></title>
            <link>https://velog.io/@emily0_0/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-%ED%95%B4%EC%8B%9C-%EC%9C%84%EC%9E%A5</link>
            <guid>https://velog.io/@emily0_0/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-%ED%95%B4%EC%8B%9C-%EC%9C%84%EC%9E%A5</guid>
            <pubDate>Thu, 22 Oct 2020 08:28:06 GMT</pubDate>
            <description><![CDATA[<p><img src="https://images.velog.io/images/emily0_0/post/59cc8fdb-895a-4ddb-a7d2-3fc3ce2ef45e/days-e's%20art.png" alt=""></p>
<p><a href="https://programmers.co.kr/learn/courses/30/lessons/42578">프로그래머스 - 위장</a></p>
<h3 id="문제-설명">문제 설명</h3>
<blockquote>
<p>스파이가 가진 서로 다른 옷의 조합의 수 <span style="color: purple">return</span>하기</p>
</blockquote>
<h3 id="제한사항">제한사항</h3>
<blockquote>
<p>스파이가 가진 의상의 수는 <strong>1개 이상 30개 이하</strong>이다.
모든 문자열의 길이는 <strong>1 이상 20 이하인 자연수</strong>이다.
모든 문자열은 <strong>알파벳 소문자</strong> 또는 <strong>_</strong> 로만 이루어져 있다.
스파이는 하루에 최소 한 개의 의상은 입는다.</p>
</blockquote>
<h3 id="문제풀이">문제풀이</h3>
<blockquote>
<p>옷의 종류를 나눠서 <strong>map</strong>을 만든다. <em>(모자, 상의, 하의끼리 나눈다.)</em>
<strong>map</strong>에서 <strong>key</strong>는 옷의 종류이고 <strong>value</strong>는 종류의 개수이다.</p>
</blockquote>
<blockquote>
<p>*<em>각 종류의 개수 + 1 *</em> 한 값을 모두 곱한다. 
1을 더하는 이유는 해당 종류의 옷을 선택하지 않는 경우를 포함하기 위해서!
결과에 1을 빼주면서 아무 옷도 입지 않는 경우를 제외시킨다.</p>
</blockquote>
<h3 id="코드">코드</h3>
<pre><code class="language-c">#include &lt;string&gt;
#include &lt;vector&gt;
#include &lt;map&gt;
#include &lt;algorithm&gt;
#include &lt;iostream&gt;

using namespace std;

int solution(vector&lt;vector&lt;string&gt;&gt; clothes) {
    int answer = 1;
    map &lt;string, int&gt; Clothes;
    vector&lt;string&gt; clothesKinds;

    for(int i=0; i&lt;clothes.size(); i++){
        if(Clothes[clothes[i][1]] == 0){
            Clothes[clothes[i][1]] = 1;
            clothesKinds.push_back(clothes[i][1]);
        }
        else{
            Clothes[clothes[i][1]]++;
        }
    }

    map &lt;string, int&gt;::iterator iter; 
    for(iter=Clothes.begin(); iter!=Clothes.end(); iter++){
        answer*=iter-&gt;second+1;
    }

    return answer-1;
}</code></pre>
<h3 id="시간-복잡도">시간 복잡도</h3>
<p>Θ(N)</p>
<h3 id="문제-풀-때-참고-사이트">문제 풀 때 참고 사이트</h3>
<p><a href="https://blockdmask.tistory.com/87">map container 정리 및 사용법</a>
<a href="https://blockdmask.tistory.com/70">vector container 정리 및 사용법</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[프로그래머스] 해시 - 전화번호 목록]]></title>
            <link>https://velog.io/@emily0_0/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-%ED%95%B4%EC%8B%9C-%EC%A0%84%ED%99%94%EB%B2%88%ED%98%B8-%EB%AA%A9%EB%A1%9D</link>
            <guid>https://velog.io/@emily0_0/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-%ED%95%B4%EC%8B%9C-%EC%A0%84%ED%99%94%EB%B2%88%ED%98%B8-%EB%AA%A9%EB%A1%9D</guid>
            <pubDate>Thu, 22 Oct 2020 08:04:27 GMT</pubDate>
            <description><![CDATA[<p><img src="https://images.velog.io/images/emily0_0/post/9683a504-dd72-4d60-a31c-00e31fbf91a0/Image%20about%20cartoon%20in%2090%E2%80%99s%20%E2%9D%A4%EF%B8%8F%20by%20For%20The%20Culture%E2%80%BC%EF%B8%8F.png" alt=""></p>
<p><a href="https://programmers.co.kr/learn/courses/30/lessons/42577">프로그래머스 - 전화번호 목록</a></p>
<h3 id="문제-설명">문제 설명</h3>
<blockquote>
<p>전화번호부에 적힌 전화번호 중, 한 번호가 다른 번호의 접두어인 경우 확인하기.
접두어인 경우가 있으면 <span style="color:red">false</span>를 그렇지 않으면 <span style="color:blue">true</span>를 return.</p>
</blockquote>
<h3 id="제한사항">제한사항</h3>
<blockquote>
<p><strong>phone_book</strong>의 길이는 <strong>1 이상 1,000,000 이하</strong>이다.
<strong>각 전화번호</strong>의 길이는 <strong>1 이상 20 이하</strong>이다.</p>
</blockquote>
<h3 id="문제풀이">문제풀이</h3>
<blockquote>
<p><strong>phone_book</strong> 을 정렬하고 바로 다음에 오는 값의 접두사인지 확인한다.
사전순으로 정렬했기 때문에 바로 다음 값만 확인하면 된다. </p>
</blockquote>
<h3 id="코드">코드</h3>
<pre><code class="language-c">#include &lt;string&gt;
#include &lt;vector&gt;
#include &lt;algorithm&gt;
#include &lt;iostream&gt;

using namespace std;

bool solution(vector&lt;string&gt; phone_book) {
    bool answer = true;

    sort(phone_book.begin(), phone_book.end());

    for(int i=0; i&lt;phone_book.size()-1; i++){
        if (phone_book[i] == phone_book[i+1].substr(0, phone_book[i].size())){
            answer = false;
            break;
        }
    }

    return answer;
}
</code></pre>
<h3 id="시간-복잡도">시간 복잡도</h3>
<p>O(nlogn)</p>
<h3 id="문제-풀-때-참고-사이트">문제 풀 때 참고 사이트</h3>
<p><a href="https://blockdmask.tistory.com/87">map container 정리 및 사용법</a>
<a href="https://blockdmask.tistory.com/70">vector container 정리 및 사용법</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[프로그래머스] 해시 - 완주하지 못한 선수]]></title>
            <link>https://velog.io/@emily0_0/%ED%95%B4%EC%8B%9C-%EC%99%84%EC%A3%BC%ED%95%98%EC%A7%80-%EB%AA%BB%ED%95%9C-%EC%84%A0%EC%88%98</link>
            <guid>https://velog.io/@emily0_0/%ED%95%B4%EC%8B%9C-%EC%99%84%EC%A3%BC%ED%95%98%EC%A7%80-%EB%AA%BB%ED%95%9C-%EC%84%A0%EC%88%98</guid>
            <pubDate>Thu, 22 Oct 2020 07:35:42 GMT</pubDate>
            <description><![CDATA[<p>프로그래머스 고득점 Kit을 풀어보려고 한다.</p>
<p><img src="https://images.velog.io/images/emily0_0/post/b5ac63ef-559e-460d-a02d-f74836e7c139/City%20Marathon%20by%20Faber14%20on%20Envato%20Elements.jpeg" alt=""></p>
<p><a href="https://programmers.co.kr/learn/courses/30/lessons/42576">프로그래머스 - 완주하지 못한 선수</a></p>
<h3 id="문제-설명">문제 설명</h3>
<blockquote>
<p><strong>participant</strong>과 <strong>completion</strong>을 비교해서 완주하지 못한 선수의 이름을 return한다.</p>
</blockquote>
<h3 id="제한사항">제한사항</h3>
<blockquote>
<p>완주하지 못한 선수는 항상 1명이다.
마라톤 경기에 참여한 선수의 수 는 <strong>1 ~ 100,000</strong>명이다.
참가자의 이름은 1개 이상 20개 이하의 알파벳 소문자.
<strong>동명이인</strong>이 존재한다.</p>
</blockquote>
<h3 id="문제풀이">문제풀이</h3>
<blockquote>
<p><strong>participant</strong>과 <strong>completion</strong>을 정렬하고 같은 index에 같은 값이 있는지 확인한다.</p>
</blockquote>
<blockquote>
<p>다른 경우 <strong>participant</strong>에 있던 값을 <strong>answer</strong>에 저장한다.</p>
</blockquote>
<h3 id="코드">코드</h3>
<pre><code class="language-c">#include &lt;string&gt;
#include &lt;vector&gt;
#include &lt;algorithm&gt;

using namespace std;

string solution(vector&lt;string&gt; participant, vector&lt;string&gt; completion) {
    string answer = &quot;&quot;;

    sort(participant.begin(), participant.end());
    sort(completion.begin(), completion.end());

    answer = participant[participant.size()-1];

    for(int i=0; i&lt;completion.size(); i++){
        if(completion[i] != participant[i]){
            answer = participant[i];
            break;
        }
    }

    return answer;
}</code></pre>
<h3 id="문제-풀-때-참고-사이트">문제 풀 때 참고 사이트</h3>
<p><a href="https://blockdmask.tistory.com/87">map container 정리 및 사용법</a>
<a href="https://blockdmask.tistory.com/70">vector container 정리 및 사용법</a></p>
]]></description>
        </item>
    </channel>
</rss>