<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>inss_.log</title>
        <link>https://velog.io/</link>
        <description>💻💡👻</description>
        <lastBuildDate>Fri, 01 Aug 2025 09:30:45 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <copyright>Copyright (C) 2019. inss_.log. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/inss_" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[[프로그래머스] LV2. 주차 요금 계산
]]></title>
            <link>https://velog.io/@inss_/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-LV2.-%EC%A3%BC%EC%B0%A8-%EC%9A%94%EA%B8%88-%EA%B3%84%EC%82%B0</link>
            <guid>https://velog.io/@inss_/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-LV2.-%EC%A3%BC%EC%B0%A8-%EC%9A%94%EA%B8%88-%EA%B3%84%EC%82%B0</guid>
            <pubDate>Fri, 01 Aug 2025 09:30:45 GMT</pubDate>
            <description><![CDATA[<h3 id="💡풀이">💡풀이</h3>
<ul>
<li>차량 내역이 담긴 배열(records) 순회하면서 treeMap에 각 차량번호와 누적 시간 담기
=&gt; 시간을 분단위로 계산 후, IN일 경우는 더하기, OUT일 경우는 빼기</li>
<li>treeMap에 저장된 누적 시간에 따라 요금 계산하기
=&gt; 누적 시간이 양수이면 OUT이 없는 차량이므로 23:59으로 OUT 계산 후 treeMap에 넣기
=&gt; 요금 계산 후 배열에 넣기 (calFees 함수)</br>

</li>
</ul>
<p>👍🏼 원래는 HashMap에 넣고 Key 기준으로 정렬하려고 했는데 TreeMap이 생각나서 다시 수정함 ! (TreeMap : Key 기준으로 자동 정렬)
🚨 주의 ) Math.ceil로 올림할 때 Double형으로 계산하고 올림해야함 (int형으로 나눗셈하면 안됨)</p>
<pre><code class="language-java">import java.util.*;

class Solution {
    static int defTime, defFee, unitTime, unitFee;
    public int[] solution(int[] fees, String[] records) {
        defTime = fees[0];
        defFee = fees[1];
        unitTime = fees[2];
        unitFee = fees[3];

        // treeMap에 차량번호와 각각 시간 담기
        Map&lt;String, Integer&gt; recMap = new TreeMap&lt;&gt;();
        for(String record : records){
            String[] str = record.split(&quot; &quot;);
            // 분 단위로 변경
            String[] time = str[0].split(&quot;:&quot;);
            int minute = Integer.parseInt(time[0]) * 60 + Integer.parseInt(time[1]);

            // 누적 시간 구하기
            if (str[2].equals(&quot;IN&quot;)){ // IN일 경우 시간 더하기
                 recMap.put(str[1], recMap.getOrDefault(str[1], 0) + minute);
            } else { // OUT일 경우 시간 빼기
                recMap.put(str[1], recMap.getOrDefault(str[1], 0) - minute);
            }
        }

        // treeMap에 각 차량번호에 따라 누적 시간 요금 계산
        int idx = 0;
        int[] answer = new int[recMap.size()];  // 결과 배열
        for(String rec : recMap.keySet()){
            if (recMap.get(rec) &gt;= 0){  // OUT이 입력되지 않았으면 23:59을 OUT으로 계산하기
                recMap.put(rec, recMap.get(rec) - (23 * 60 + 59));
            }
            // 요금 계산 후 배열에 넣기
            answer[idx++] = calFees(recMap.get(rec) * -1);
        }

        return answer;
    }

    public int calFees(int time){
        if (time &lt; defTime) return defFee;
        return defFee + (int)Math.ceil(Double.valueOf(time - defTime) / Double.valueOf(unitTime)) * unitFee;
    }
}</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[[프로그래머스] LV2.k진수에서 소수 개수 구하기]]></title>
            <link>https://velog.io/@inss_/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-LV2.k%EC%A7%84%EC%88%98%EC%97%90%EC%84%9C-%EC%86%8C%EC%88%98-%EA%B0%9C%EC%88%98-%EA%B5%AC%ED%95%98%EA%B8%B0</link>
            <guid>https://velog.io/@inss_/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-LV2.k%EC%A7%84%EC%88%98%EC%97%90%EC%84%9C-%EC%86%8C%EC%88%98-%EA%B0%9C%EC%88%98-%EA%B5%AC%ED%95%98%EA%B8%B0</guid>
            <pubDate>Sun, 27 Jul 2025 15:23:44 GMT</pubDate>
            <description><![CDATA[<h3 id="💡-풀이">💡 풀이</h3>
<ul>
<li>k진수로 변환할 때 나눈 나머지를 StringBuilder에 저장하고 마지막에 문자열을 뒤집어서 진수로 변환</li>
<li>진수로 바꾼 숫자를 0을 기준으로 분리</li>
<li>분리해서 각 숫자가 소수인지 판별</li>
<li>🚨 주의 -&gt; 시간초과 발생<ul>
<li>long 자료형 필요 -&gt; n의 최대값인 1,000,000을 2진수로 변환하면 2^19로 19자리쯤 되는 10진수로 변환됨 </li>
<li>소수 판별할 때 n의 제곱근보다 작은 자연수로 확인하기 -&gt; 0 기준으로 분리했을 때 특정 값이 &quot;1122222222221&quot; 이렇게 크다면 n보다 작은 수로 반복문 돌면서 확인하면 너무 오래걸림</li>
</ul>
</li>
</ul>
<pre><code class="language-java">import java.util.*;

class Solution {
    public int solution(int n, int k) {
        int answer = 0;

        String num = calNum(n, k); // 진수 계산
        String[] splitNum = num.split(&quot;0&quot;); // 0을 기준으로 분리하기
        for(String s : splitNum){
            if (s.isEmpty()) continue;
            if (isPrime(Long.parseLong(s))) answer++;
        }

        return answer;
    }

    // k진수로 변환
    public String calNum(int num, int k){
        StringBuilder sb = new StringBuilder();

        while(num &gt;= k){
            long n = num % k;
            sb.append(String.valueOf(n));
            num /= k;
        }
        sb.append(num);
        return sb.reverse().toString();
    }

    // 소수 판별
    public boolean isPrime(long num){
        if (num &lt;= 1) return false;
        for(int i = 2; i&lt;=Math.sqrt(num); i++){
            if (num % i == 0) return false;
        }
        return true;
    }
}</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[[프로그래머스] LV1. 신고 결과 받기]]></title>
            <link>https://velog.io/@inss_/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-LV1.-%EC%8B%A0%EA%B3%A0-%EA%B2%B0%EA%B3%BC-%EB%B0%9B%EA%B8%B0</link>
            <guid>https://velog.io/@inss_/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-LV1.-%EC%8B%A0%EA%B3%A0-%EA%B2%B0%EA%B3%BC-%EB%B0%9B%EA%B8%B0</guid>
            <pubDate>Sun, 27 Jul 2025 14:41:39 GMT</pubDate>
            <description><![CDATA[<h3 id="💡-풀이">💡 풀이</h3>
<ul>
<li>cntMap : 유저별 신고 당한 횟수 카운트</li>
<li>idMap : 유저별 신고한 ID 리스트로 넣기</li>
<li>reportSet : report 중복 제거</li>
<li>cntMap의 value를 확인하면서 k 이상 신고 당한 유저를 리스트에 넣기</li>
<li>idMap을 돌면서 유저가 신고한 ID 리스트 중에 정지당한 유저가 있으면 resCnt++</li>
</ul>
<pre><code class="language-java">import java.util.*;

class Solution {
    public int[] solution(String[] id_list, String[] report, int k) {
        HashMap&lt;String, Integer&gt; cntMap = new HashMap&lt;&gt;(); // 신고당한 횟수
        HashMap&lt;String, ArrayList&lt;String&gt;&gt; idMap = new HashMap&lt;&gt;(); // 유저별 신고한 ID 
        HashSet&lt;String&gt; reportSet = new HashSet&lt;&gt;(); 

        // idMap에 유저 넣기
        for(int i = 0; i&lt;id_list.length; i++){
            idMap.put(id_list[i], new ArrayList&lt;String&gt;());
        }
        // report 중복 제거
        for(String rep : report){
            reportSet.add(rep);
        }

        // 신고당한 횟수와 해당 유저가 신고한 ID 각각 해시맵에 넣기
        for(String rep : reportSet){
            String[] input = rep.split(&quot; &quot;);
            cntMap.put(input[1], cntMap.getOrDefault(input[1], 0) + 1);
            idMap.get(input[0]).add(input[1]);
        }

        // 신고당한 횟수가 k 이상인 유저 리스트에 넣기 
        ArrayList&lt;String&gt; banned = new ArrayList&lt;&gt;();
        for(String cnt : cntMap.keySet()){
            if (cntMap.get(cnt) &gt;= k) banned.add(cnt);
        }

        // idMap을 돌면서 신고한 ID 중 정지당한 ID 있으면 count
        int[] answer = new int[id_list.length];
        for(int i = 0; i&lt;id_list.length; i++){
            ArrayList&lt;String&gt; check = idMap.get(id_list[i]);
            int resCnt = 0;
            for(String c : check){
                if (banned.contains(c)) resCnt++;
            }
            answer[i] = resCnt;
        }

        return answer;
    }
}</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[[프로그래머스] 식품분류별 가장 비싼 식품의 정보 조회하기
]]></title>
            <link>https://velog.io/@inss_/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-%EC%8B%9D%ED%92%88%EB%B6%84%EB%A5%98%EB%B3%84-%EA%B0%80%EC%9E%A5-%EB%B9%84%EC%8B%BC-%EC%8B%9D%ED%92%88%EC%9D%98-%EC%A0%95%EB%B3%B4-%EC%A1%B0%ED%9A%8C%ED%95%98%EA%B8%B0</link>
            <guid>https://velog.io/@inss_/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-%EC%8B%9D%ED%92%88%EB%B6%84%EB%A5%98%EB%B3%84-%EA%B0%80%EC%9E%A5-%EB%B9%84%EC%8B%BC-%EC%8B%9D%ED%92%88%EC%9D%98-%EC%A0%95%EB%B3%B4-%EC%A1%B0%ED%9A%8C%ED%95%98%EA%B8%B0</guid>
            <pubDate>Thu, 17 Jul 2025 14:54:29 GMT</pubDate>
            <description><![CDATA[<h3 id="🚨-틀린-코드">🚨 틀린 코드</h3>
<p><img src="https://velog.velcdn.com/images/inss_/post/8b8683b2-b759-4436-9561-e97516b558c6/image.png" alt=""></p>
<ul>
<li>카테고리로 그룹화 후에 MAX 집계함수로 비싼 식품 나오게 했음
🫥 분명히 맞는데.. 자꾸 틀려서 헤매다가 </li>
<li><blockquote>
<p>group by에 없는 컬럼이고 집계함수도 아닌 컬럼을 select에 사용해서 상품 이름이 정확히 매핑되지 않음 =&gt; 서브쿼리 필요</p>
</blockquote>
</li>
</ul>
<pre><code class="language-sql">SELECT CATEGORY, MAX(PRICE) AS MAX_PRICE, PRODUCT_NAME
FROM FOOD_PRODUCT
GROUP BY CATEGORY
HAVING CATEGORY IN (&#39;과자&#39;, &#39;국&#39;, &#39;김치&#39;, &#39;식용유&#39;)
ORDER BY MAX_PRICE DESC</code></pre>
</br>
</br>

<h3 id="💡-풀이">💡 풀이</h3>
<ul>
<li>서브쿼리를 통해 그룹화해서 카테고리별 가장 큰 금액과 카테고리명 가져오기</li>
<li>where절에서 해당 카테고리와 금액인 칼럼 출력<pre><code class="language-sql">SELECT CATEGORY, PRICE AS MAX_PRICE, PRODUCT_NAME
FROM FOOD_PRODUCT
WHERE (CATEGORY, PRICE) IN (
  SELECT CATEGORY, MAX(PRICE)
  FROM FOOD_PRODUCT
  GROUP BY CATEGORY
  HAVING CATEGORY IN (&#39;과자&#39;, &#39;국&#39;, &#39;김치&#39;, &#39;식용유&#39;)
)
ORDER BY MAX_PRICE DESC</code></pre>
</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[프로그래머스] LV2. 두 큐 합 같게 만들기]]></title>
            <link>https://velog.io/@inss_/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-LV2.-%EB%91%90-%ED%81%90-%ED%95%A9-%EA%B0%99%EA%B2%8C-%EB%A7%8C%EB%93%A4%EA%B8%B0</link>
            <guid>https://velog.io/@inss_/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-LV2.-%EB%91%90-%ED%81%90-%ED%95%A9-%EA%B0%99%EA%B2%8C-%EB%A7%8C%EB%93%A4%EA%B8%B0</guid>
            <pubDate>Thu, 17 Jul 2025 14:34:10 GMT</pubDate>
            <description><![CDATA[<h3 id="🚨-실패-코드">🚨 실패 코드</h3>
<ul>
<li>각 배열을 각각 큐에 넣고, 합계도 구하기</li>
<li>queue1의 합이 queue2의 합보다 더 작으면 queue2에서 꺼내서 queue1에 넣기</li>
<li>반대로 queue2도 더 작으면 queue1 원소 넣기</li>
<li>큐에서 넣을때 해당 큐에 원소가 하나밖에 없으면 같은 합을 못 만드므로 -1 리턴
🫥 테스트케이스 30개중 5개 시간초과<pre><code class="language-java">import java.util.*;
</code></pre>
</li>
</ul>
<p>class Solution {
    public int solution(int[] queue1, int[] queue2) {
        int answer = 0;
        int sum1 = 0;
        int sum2 = 0;
        int total = sum1 + sum2;
        Queue<Integer> q1 = new LinkedList&lt;&gt;(); 
        Queue<Integer> q2 = new LinkedList&lt;&gt;();
        for(int i = 0; i&lt;queue1.length; i++){
            sum1 += queue1[i];
            sum2 += queue2[i];</p>
<pre><code>        q1.add(queue1[i]);
        q2.add(queue2[i]);
    }

    while(sum1 != sum2){
        if (sum1 &lt; sum2){
            if (q2.size() == 1) return -1;
            int n = q2.poll();
            sum1 += n;
            sum2 -= n;
            q1.add(n);
        } else {
            if (q1.size() == 1) return -1;
            int n = q1.poll();
            sum2 += n;
            sum1 -= n;
            q2.add(n);
        }
        answer++;
    }


    return answer;
}</code></pre><p>}</p>
<pre><code>![](https://velog.velcdn.com/images/inss_/post/f4ad61dd-fcab-4492-b2fe-d9c2d2ff7d2c/image.png)

&lt;/br&gt;
&lt;/br&gt;

### 💡 풀이
- queue2 원소 합은 굳이 필요 없이 queue1 원소 합이랑 total 원소 합 구하기
- 위 코드에서 실패했던 이유는 다 순회해서 결국 처음 큐의 원소와 같아졌으면 더이상 반복할 필요 없어서 return -1
- queue1.length * 4는 (queue1.length + queue2.length) * 2를 의미
```java
import java.util.*;

class Solution {
    public int solution(int[] queue1, int[] queue2) {
        int answer = 0;
        long sum1 = 0;
        long total = 0;
        Queue&lt;Integer&gt; q1 = new LinkedList&lt;&gt;(); 
        Queue&lt;Integer&gt; q2 = new LinkedList&lt;&gt;();
        for(int i = 0; i&lt;queue1.length; i++){
            sum1 += queue1[i];
            total += queue1[i] + queue2[i];

            q1.add(queue1[i]);
            q2.add(queue2[i]);
        }

        while(sum1 != total/2){
            // 다 순회하고 결국 다시 원래 자리로 오면 return
            if (answer &gt; queue1.length * 4) return -1;

            if (sum1 &lt; total/2){
                if (q2.size() == 1) return -1;
                int n = q2.poll();
                sum1 += n;
                q1.add(n);
            } else {
                if (q1.size() == 1) return -1;
                int n = q1.poll();
                sum1 -= n;
                q2.add(n);
            }
            answer++;


        }


        return answer;
    }

}</code></pre>]]></description>
        </item>
        <item>
            <title><![CDATA[[프로그래머스] LV1. 개인정보 수집 유효기간]]></title>
            <link>https://velog.io/@inss_/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-LV1.-%EA%B0%9C%EC%9D%B8%EC%A0%95%EB%B3%B4-%EC%88%98%EC%A7%91-%EC%9C%A0%ED%9A%A8%EA%B8%B0%EA%B0%84</link>
            <guid>https://velog.io/@inss_/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-LV1.-%EA%B0%9C%EC%9D%B8%EC%A0%95%EB%B3%B4-%EC%88%98%EC%A7%91-%EC%9C%A0%ED%9A%A8%EA%B8%B0%EA%B0%84</guid>
            <pubDate>Fri, 11 Jul 2025 08:07:44 GMT</pubDate>
            <description><![CDATA[<h3 id="💡-풀이">💡 풀이</h3>
<ul>
<li>String 날짜를 일수로 변경해주는 함수 =&gt; toDays</li>
<li>약관 종류와 유효기간 Map에 담기</li>
<li>privacies 하나씩 확인하면서 개인정보 수집 일자 + 유효기간 일수 구하기</li>
<li>오늘 날짜 일수와 비교해서 오늘 날짜가 더 크면 만료기간이 지났으므로 정답 리스트에 담기</li>
<li>⭐ &quot;2021.01.11&quot; . 기준으로 나눌 때 split(&quot;.&quot;) 아닌 split(&quot;\.&quot;)으로 해야함 </li>
<li><blockquote>
<p>전자로 하면 .(dot)을 모든 문자를 기준으로 나뉨</p>
</blockquote>
<pre><code class="language-java">import java.util.*;
</code></pre>
</li>
</ul>
<p>class Solution {
    public int[] solution(String today, String[] terms, String[] privacies) {
        int todays = toDays(today); // 오늘 날짜 일수로 변경 
        ArrayList<Integer> res = new ArrayList&lt;&gt;();</p>
<pre><code>    // 약관 종류와 유효기간 map에 담기
    HashMap&lt;String, Integer&gt; termMap = new HashMap&lt;&gt;();
    for(String term : terms){
        termMap.put(term.split(&quot; &quot;)[0], Integer.parseInt(term.split(&quot; &quot;)[1]));
    }

    for(int i = 0; i&lt;privacies.length; i++){
        String[] sp = privacies[i].split(&quot; &quot;);
        // 개인정보 수집 일자 + 유효기간
        int expDays = toDays(sp[0]) + termMap.get(sp[1]) * 28;

        if (todays &gt;= expDays) res.add(i+1);
    }

    // list에 담은 정답 배열로 옮기기
    int[] answer = new int[res.size()];
    int idx = 0;
    for(int r : res){
        answer[idx++] = r;
    }
    return answer;
}

// 일수로 변경 메소드
public int toDays(String date){
    String[] d = date.split(&quot;\\.&quot;);
    int year = Integer.parseInt(d[0]);
    int month = Integer.parseInt(d[1]);
    int day = Integer.parseInt(d[2]);

    return year * 12 * 28 + month * 28 + day;
}</code></pre><p>}
```</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[프로그래머스] LV2. 거리두기 확인하기]]></title>
            <link>https://velog.io/@inss_/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-LV2.-%EA%B1%B0%EB%A6%AC%EB%91%90%EA%B8%B0-%ED%99%95%EC%9D%B8%ED%95%98%EA%B8%B0</link>
            <guid>https://velog.io/@inss_/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-LV2.-%EA%B1%B0%EB%A6%AC%EB%91%90%EA%B8%B0-%ED%99%95%EC%9D%B8%ED%95%98%EA%B8%B0</guid>
            <pubDate>Tue, 08 Jul 2025 15:10:17 GMT</pubDate>
            <description><![CDATA[<h3 id="💡-풀이">💡 풀이</h3>
<ul>
<li>place 배열 돌면서 응시자(P) 확인 후 List에 넣기, 2차원 배열에 응시자, 테이블, 파티션 정보 넣기</li>
<li>응시자 리스트에 2중 for문으로 두명씩 확인하기 =&gt; isCheck</li>
<li>두 응시자의 맨해튼 거리가 1이면 무조건 false
  2이면 두 응시자 거리가 직선인 경우, 대각선인 경우 생각해서 테이블(X)이 있는지 확인하기 =&gt; checkPartition</li>
</ul>
<pre><code class="language-java">import java.util.*;

class Solution {
    public int[] solution(String[][] places) {
        int[] answer = new int[5];
        int idx = 0;
        for(String[] place : places){
            ArrayList&lt;int[]&gt; pList = new ArrayList&lt;&gt;(); // 응시자 좌표 담기
            String[][] arr = new String[5][5];   // place 2차원 배열에 담기

            for(int i = 0; i&lt;place.length; i++){
                String p = place[i];
                for(int j = 0; j&lt;p.length(); j++){
                    if (p.charAt(j) == &#39;P&#39;) pList.add(new int[]{i, j});
                    arr[i][j] = String.valueOf(p.charAt(j));
                }
            }

            // isCheck 함수로 거리두기 확인하기
            answer[idx++] = isCheck(pList, arr) ? 1 : 0;
        }
        return answer;
    }


    public boolean isCheck(ArrayList&lt;int[]&gt; pList, String[][] arr){
        for(int i = 0; i&lt;pList.size(); i++){
            for(int j = i + 1; j&lt;pList.size(); j++){
                // 거리두기를 하라도 안지킨 응시자가 있으면 false 후 종료
                if (!checkPartition(pList.get(i), pList.get(j), arr)) {
                    return false;
                }
            }
        }

        return true;
    }

    // 거리두기 확인
    public boolean checkPartition(int[] a, int[] b, String[][] arr){
        int x1 = a[0], y1 = a[1];
        int x2 = b[0], y2 = b[1];

        int dist = Math.abs(x1 - x2) + Math.abs(y1 - y2);

        // 거리가 1인 경우
        if (dist == 1) return false;

        // 거리가 2인 경우
        if (dist == 2) {
            // 두 응시자 거리가 직선인 경우
            if (x1 == x2) return arr[x1][(y1 + y2) / 2].equals(&quot;X&quot;);
            else if (y1 == y2) return arr[(x1 + x2) / 2][y2].equals(&quot;X&quot;);
            // 대각선인 경우
            else return arr[x2][y1].equals(&quot;X&quot;) &amp;&amp; arr[x1][y2].equals(&quot;X&quot;);
        } 

        return true;
    }
}</code></pre>
<p>🫥 처음에는 무조건 조합 알고리즘 써서 2명씩 뽑고 확인하려고 했는데 그냥 2명만 뽑으면 되니까 이중 for문으로 간단하게 해도 됐다 ..!</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[프로그래머스] LV3. 보석 쇼핑]]></title>
            <link>https://velog.io/@inss_/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-LV3.-%EB%B3%B4%EC%84%9D-%EC%87%BC%ED%95%91</link>
            <guid>https://velog.io/@inss_/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-LV3.-%EB%B3%B4%EC%84%9D-%EC%87%BC%ED%95%91</guid>
            <pubDate>Mon, 07 Jul 2025 13:45:25 GMT</pubDate>
            <description><![CDATA[<h3 id="🚨-첫번째-실패-풀이">🚨 첫번째 실패 풀이</h3>
<p>✔️ 2중 for문</p>
<ul>
<li>보석 종류 수 세기 위해서 Set에 넣고 크기 구하기</li>
<li>보석 첫번째 부터 2중 for문 돌면서 새로운 set에 넣고 현재 확인 중인 set 크기랑 보석 종류 수 같고, 구간이 짧으면 answer 배열에 넣기</li>
<li>😓 뭐야 쉽네???? 했지만 효율성에서 실패
<img src="https://velog.velcdn.com/images/inss_/post/81fd9979-63cc-42dd-96fa-43c5950c357e/image.png" alt=""><pre><code class="language-java">import java.util.*;
</code></pre>
</li>
</ul>
<p>class Solution {
    public int[] solution(String[] gems) {
        Set<String> set = new HashSet&lt;&gt;();
        for(String gem : gems){
            set.add(gem);
        }</p>
<pre><code>    int[] answer = new int[2];
    int result = Integer.MAX_VALUE;
    for(int i = 0; i&lt;gems.length; i++){
        Set&lt;String&gt; s = new HashSet&lt;&gt;();
        for(int j = i; j&lt;gems.length; j++){
            s.add(gems[j]);

            if(set.size() == s.size()) {
                if (result &gt; j - i) {
                    result = j - i;
                    answer[0] = i + 1;
                    answer[1] = j + 1;
                }
                break;
            }
        } 
    }


    return answer;
}</code></pre><p>}</p>
<pre><code>
&lt;/br&gt;
&lt;/br&gt;

### 🚨 두번째 실패 풀이
✔️ 투포인터 + HashSet
- 이중탐색으로 생각해봤지만 아무리 생각해도 모르겠어서 GPT 한테 힌트를 구하니까 (까먹고 있었던) 투포인터를 사용하라고 했다..!
- 투포인터를 사용하는데 계속 left = 0, right = 배열 사이즈 로 생각 하니까 잘 안풀렸는데 left = 0, right = 0 으로도 풀 수 있었음
- 😓 하지만 while문 안에 또 for문으로 효율성 실패
![](https://velog.velcdn.com/images/inss_/post/1a2f2370-5794-4434-9a87-e9aae1742d94/image.png)
```java
import java.util.*;

class Solution {
    public int[] solution(String[] gems) {
        Set&lt;String&gt; set = new HashSet&lt;&gt;(Arrays.asList(gems));
        int targetCnt = set.size();

        int left = 0, right = 0;
        int[] answer = new int[2];
        int cnt = Integer.MAX_VALUE;
        while(left &lt;= right &amp;&amp; right &lt; gems.length){
            Set&lt;String&gt; check = new HashSet&lt;&gt;();
            for(int i = left; i&lt;=right; i++){
                check.add(gems[i]);
            }

            if (check.size() &lt; targetCnt) right++;
            else if (check.size() == targetCnt) {
                if(cnt &gt; right - left){
                    answer[0] = left+1;
                    answer[1] = right+1;

                    cnt = right - left;
                }

                left++;

            }
        }


        return answer;
    }
}</code></pre></br>
</br>

<h3 id="💡-정답-풀이">💡 정답 풀이</h3>
<p>✔️ 투포인터 + HashMap</p>
<ul>
<li><del>데이터를 1번만 순회해야 효율성에 통과해야하는 데 떠오르지 않아서 다른 사람 풀이 참고 ..</del></li>
<li>보석을 하나씩 추가하는데 해시맵에 저장해서 몇개가 들어있는지 Count =&gt; 다음에 right +1 </li>
<li>해시맵에 보석 종류가 다 들어온 경우 (= 해시맵 사이즈가 종류 수랑 같은 경우) 
  =&gt; 짧은 구간 찾아서 answer 배열 갱신
  =&gt; 더 짧은 구간 있는지 파악하기 위해 left 증가, 이때 증가하기전에 해시맵에서 left 지점에 있는 보석 수 빼기<pre><code class="language-java">import java.util.*;
</code></pre>
</li>
</ul>
<p>class Solution {
    public int[] solution(String[] gems) {
        Set<String> set = new HashSet&lt;&gt;(Arrays.asList(gems));
        int types = set.size();</p>
<pre><code>    int left = 0, right = 0;
    int[] answer = new int[2];
    int minLen = Integer.MAX_VALUE;

    HashMap&lt;String, Integer&gt; gem = new HashMap&lt;&gt;();
    while(right &lt; gems.length){
        // 보석 추가
        gem.put(gems[right], gem.getOrDefault(gems[right], 0) + 1);
        right++;

        // gem 해시맵에 보석이 다 들어온 경우
        while (gem.size() == types) {
            // 보석 중 짧은 구간 찾기
            if (minLen &gt; right - left){
                answer[0] = left+1;
                answer[1] = right;

                minLen = right - left;
            }

            // left 위치 늘리고 기존 left는 gem 해시맵에서 제거
            gem.put(gems[left], gem.get(gems[left]) - 1);
            if (gem.get(gems[left]) == 0){
                gem.remove(gems[left]);
            }
            left++;

        }
    }


    return answer;
}</code></pre><p>}</p>
<pre><code></code></pre>]]></description>
        </item>
        <item>
            <title><![CDATA[[BOJ-Gold4] 1504번 특정한 최단 경로]]></title>
            <link>https://velog.io/@inss_/BOJ-Gold4-1504%EB%B2%88-%ED%8A%B9%EC%A0%95%ED%95%9C-%EC%B5%9C%EB%8B%A8-%EA%B2%BD%EB%A1%9C</link>
            <guid>https://velog.io/@inss_/BOJ-Gold4-1504%EB%B2%88-%ED%8A%B9%EC%A0%95%ED%95%9C-%EC%B5%9C%EB%8B%A8-%EA%B2%BD%EB%A1%9C</guid>
            <pubDate>Sun, 06 Jul 2025 15:47:43 GMT</pubDate>
            <description><![CDATA[<h3 id="💡풀이">💡풀이</h3>
<ul>
<li>a, b 정점을 무조건 거쳐야 하므로 2가지로 나눠서 생각
1) 1 -&gt; a -&gt; b -&gt; n 
2) 1 -&gt; b -&gt; a -&gt; n</li>
<li>그리고 각각 다익스트라 실행 (1에서 a, a에서 b, b에서 n)</li>
<li>최단 거리 테이블을 Integer.MAX_VALUE로 설정했다가 오버플로우 발생 =&gt; 간선이 없는 경우 MAX_VALUE를 3번 더하는 상황 발생</li>
<li>최대 간선 수 * 최대 가중치인 200,000,000으로 설정해야함 </li>
</ul>
<pre><code class="language-java">import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

import java.util.ArrayList;
import java.util.PriorityQueue;
import java.util.StringTokenizer;

public class Main {
    static class Node{
        int v; // 간선
        int cost; // 가중치

        public Node(int v, int cost){
            this.v = v;
            this.cost = cost;
        }
    }

    static ArrayList&lt;ArrayList&lt;Node&gt;&gt; graph; // 노드 정보 담는 리스트
    static boolean[] visited; // 방문 처리
    static int[] dist; // 최단 거리 테이블
    static int v, e;
    static int INF = 200000000; // 최대 간선 수 * 최대 가중치

    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer st = new StringTokenizer(br.readLine());
        v = Integer.parseInt(st.nextToken());
        e = Integer.parseInt(st.nextToken());

        graph = new ArrayList&lt;&gt;();

        // 그래프와 최단 거리 테이블 초기화
        for(int i = 0; i&lt;=v; i++){
            graph.add(new ArrayList&lt;&gt;());
        }

        for(int i = 0; i&lt;e; i++){
            st = new StringTokenizer(br.readLine());
            int U = Integer.parseInt(st.nextToken());
            int V = Integer.parseInt(st.nextToken());
            int W = Integer.parseInt(st.nextToken());

            // 양방향
            graph.get(U).add(new Node(V, W));
            graph.get(V).add(new Node(U, W));
        }

        st = new StringTokenizer(br.readLine());
        int a = Integer.parseInt(st.nextToken());
        int b = Integer.parseInt(st.nextToken());

        // 1 -&gt; a -&gt; b -&gt; n 인 경우
        int case1 = 0;
        case1 += dijkstra(1, a);
        case1 += dijkstra(a, b);
        case1 += dijkstra(b, v);

        // 1 -&gt; b -&gt; a -&gt; n 인 경우
        int case2 = 0;
        case2 += dijkstra(1, b);
        case2 += dijkstra(b, a);
        case2 += dijkstra(a, v);

        int result = (case1 &gt;= INF &amp;&amp; case2 &gt;= INF) ? -1 : Math.min(case1, case2);
        System.out.println(result);
    }

    public static int dijkstra(int start, int end){
        // visited와 dist 초기화
        visited = new boolean[v + 1];
        dist = new int[v + 1];
        for(int i = 0; i&lt;=v; i++){
            dist[i] = INF;
        }

        PriorityQueue&lt;Node&gt; queue = new PriorityQueue&lt;&gt;((a, b) -&gt; a.cost - b.cost);
        queue.add(new Node(start, 0));
        dist[start] = 0;

        while(!queue.isEmpty()){
            Node curr = queue.poll();
            int currV = curr.v;

            if (!visited[currV]){
                visited[currV] = true;

                for(Node n : graph.get(currV)){
                    if (!visited[n.v] &amp;&amp; dist[n.v] &gt; dist[currV] + n.cost){
                        dist[n.v] = dist[currV] + n.cost;
                        queue.add(new Node(n.v, dist[n.v]));
                    }
                }
            }
        }
        return dist[end];
    }
}</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[[알고리즘] 다익스트라]]></title>
            <link>https://velog.io/@inss_/%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98-%EB%8B%A4%EC%9D%B5%EC%8A%A4%ED%8A%B8%EB%9D%BC</link>
            <guid>https://velog.io/@inss_/%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98-%EB%8B%A4%EC%9D%B5%EC%8A%A4%ED%8A%B8%EB%9D%BC</guid>
            <pubDate>Fri, 04 Jul 2025 17:17:49 GMT</pubDate>
            <description><![CDATA[<h2 id="dijkstra-최단-경로-알고리즘">Dijkstra 최단 경로 알고리즘</h2>
<ul>
<li>특정 노드에서 출발하여 다른 노드로 가는 각각의 최단 경로를 구하는알고리즘 </li>
<li>시간복잡도 : O(E logN) (N : 노드 수, E : 간선 수)</li>
<li>간선의 <strong>가중치가 양수</strong>인 경우만 가능 (음수인 경우 플로이드워셜 알고리즘 사용)</li>
<li>그리디 알고리즘 사용</li>
<li><strong>우선순위 큐</strong>(힙 자료구조) 사용<blockquote>
<p>동작과BR</p>
<ol>
<li>출발 노드를 설정</li>
<li>최단 거리 테이블 초기화</li>
<li>방문하지 않은 노드 중에서 최단 거리(가중치)가 가장 짧은 노드 선택</li>
<li>해당 노드를 거쳐 다른 노드로 가는 비용 계산하여 최단 거리 테이블 갱신</li>
<li>3, 4번 반복</li>
</ol>
</blockquote>
</li>
</ul>
</br>
</br>

<h2 id="구현">구현</h2>
<p><img src="https://velog.velcdn.com/images/inss_/post/24512dbc-66c1-42fc-ad2b-ba3a064ad70d/image.png" alt=""></p>
<ol>
<li><p>출발 지점의 노드가 1이므로 우선순위 큐에 넣기, 출발 노드에서 출발 노드로의 거리는 0이므로 0으로 초기화</p>
<table>
<thead>
<tr>
<th align="center">노드 번호</th>
<th align="center">1</th>
<th align="center">2</th>
<th align="center">3</th>
<th align="center">4</th>
<th align="center">5</th>
</tr>
</thead>
<tbody><tr>
<td align="center">가중치</td>
<td align="center">0</td>
<td align="center">MAXVALUE</td>
<td align="center">MAXVALUE</td>
<td align="center">MAXVALUE</td>
<td align="center">MAXVALUE</td>
</tr>
<tr>
<td align="center">우선순위 큐 : (거리: 0, 노드: 1)</td>
<td align="center"></td>
<td align="center"></td>
<td align="center"></td>
<td align="center"></td>
<td align="center"></td>
</tr>
</tbody></table>
</li>
<li><p>큐에서 노드 꺼내기 -&gt; 해당 노드를 이미 처리했으면 무시하고 처리하지 않은 노드는 최소 비용 계산 =&gt; 2번(0 + 2), 3번(0 + 3)</p>
<p> 꺼낸 원소 : (거리: 0, 노드: 1)</p>
<table>
<thead>
<tr>
<th align="center">노드 번호</th>
<th align="center">1</th>
<th align="center">2</th>
<th align="center">3</th>
<th align="center">4</th>
<th align="center">5</th>
</tr>
</thead>
<tbody><tr>
<td align="center">가중치</td>
<td align="center">0</td>
<td align="center">2</td>
<td align="center">3</td>
<td align="center">MAXVALUE</td>
<td align="center">MAXVALUE</td>
</tr>
<tr>
<td align="center">우선순위 큐 : (거리: 2, 노드: 2), (거리: 3, 노드: 3)</td>
<td align="center"></td>
<td align="center"></td>
<td align="center"></td>
<td align="center"></td>
<td align="center"></td>
</tr>
</tbody></table>
</li>
<li><p>과정 반복 =&gt; 3번(2 + 4)은 기존 거리 3보다 크므로 넘어감, 4번(2 + 5)
 꺼낸 원소 : (거리: 2, 노드: 2)</p>
<table>
<thead>
<tr>
<th align="center">노드 번호</th>
<th align="center">1</th>
<th align="center">2</th>
<th align="center">3</th>
<th align="center">4</th>
<th align="center">5</th>
</tr>
</thead>
<tbody><tr>
<td align="center">가중치</td>
<td align="center">0</td>
<td align="center">2</td>
<td align="center">3</td>
<td align="center">7</td>
<td align="center">MAXVALUE</td>
</tr>
<tr>
<td align="center">우선순위 큐 : (거리: 3, 노드: 3), (거리: 7, 노드: 4)</td>
<td align="center"></td>
<td align="center"></td>
<td align="center"></td>
<td align="center"></td>
<td align="center"></td>
</tr>
</tbody></table>
</li>
<li><p>4번(3 + 6)으로 기존 거리 7보다 커서 넘어감
 꺼낸 원소 : (거리: 3, 노드: 3)</p>
<table>
<thead>
<tr>
<th align="center">노드 번호</th>
<th align="center">1</th>
<th align="center">2</th>
<th align="center">3</th>
<th align="center">4</th>
<th align="center">5</th>
</tr>
</thead>
<tbody><tr>
<td align="center">가중치</td>
<td align="center">0</td>
<td align="center">2</td>
<td align="center">3</td>
<td align="center">7</td>
<td align="center">MAXVALUE</td>
</tr>
<tr>
<td align="center">우선순위 큐 : (거리: 7, 노드: 4)</td>
<td align="center"></td>
<td align="center"></td>
<td align="center"></td>
<td align="center"></td>
<td align="center"></td>
</tr>
</tbody></table>
</li>
<li><p>해당 노드에서 가는 길이 없어서 큐가 비어서 종료
 꺼낸 원소 : (거리: 7, 노드: 4)</p>
<table>
<thead>
<tr>
<th align="center">노드 번호</th>
<th align="center">1</th>
<th align="center">2</th>
<th align="center">3</th>
<th align="center">4</th>
<th align="center">5</th>
</tr>
</thead>
<tbody><tr>
<td align="center">가중치</td>
<td align="center">0</td>
<td align="center">2</td>
<td align="center">3</td>
<td align="center">7</td>
<td align="center">MAXVALUE</td>
</tr>
<tr>
<td align="center">우선순위 큐 :</td>
<td align="center"></td>
<td align="center"></td>
<td align="center"></td>
<td align="center"></td>
<td align="center"></td>
</tr>
</tbody></table>
</li>
</ol>
</br>
</br>

<h3 id="⭐-관련-문제">⭐ 관련 문제</h3>
<h4 id="백준-1753번-최단경로">백준 1753번 최단경로</h4>
<pre><code class="language-java">import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

import java.util.ArrayList;
import java.util.PriorityQueue;
import java.util.StringTokenizer;

public class Main {
    static class Node{
        int v; // 간선
        int cost; // 가중치

        public Node(int v, int cost){
            this.v = v;
            this.cost = cost;
        }
    }

    static ArrayList&lt;Node&gt;[] graph; // 노드 정보 담는 리스트
    static boolean[] visited; // 방문 처리
    static int[] dist; // 최단 거리 테이블

    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer st = new StringTokenizer(br.readLine());
        int v = Integer.parseInt(st.nextToken());
        int e = Integer.parseInt(st.nextToken());
        int s = Integer.parseInt(br.readLine());

        graph = new ArrayList[v + 1];
        visited = new boolean[v + 1];
        dist = new int[v + 1];

        // 그래프와 최단 거리 테이블 초기화
        for(int i = 1; i&lt;=v; i++){
            graph[i] = new ArrayList&lt;&gt;();
            dist[i] = Integer.MAX_VALUE;
        }

        for(int i = 0; i&lt;e; i++){
            // u -&gt; v로 가는 가중치 w
            st = new StringTokenizer(br.readLine());
            int U = Integer.parseInt(st.nextToken());
            int V = Integer.parseInt(st.nextToken());
            int W = Integer.parseInt(st.nextToken());

            graph[U].add(new Node(V, W));
        }

        // 다익스트라 수행
        dijkstra(s);
        for(int i = 1; i&lt;=v; i++){
            System.out.println((dist[i] == Integer.MAX_VALUE ? &quot;INF&quot; : dist[i]));
        }

    }

    static void dijkstra(int start){
        // 우선순위 큐 사용 - 가중치 기준으로 오름차순
        PriorityQueue&lt;Node&gt; queue = new PriorityQueue&lt;&gt;((a, b) -&gt; a.cost - b.cost);
        queue.add(new Node(start, 0));
        dist[start] = 0;

        while(!queue.isEmpty()){
            // 최단 거리가 짧은 노드 꺼내기
            Node curr = queue.poll();
            int currV = curr.v;

            // 이미 방문한 노드는 무시
            if (!visited[currV]) {
                visited[currV] = true;

                for(Node n : graph[currV]){
                    int v = n.v;
                    int cost = n.cost;

                    // 현재 노드 거리 + 확인하는 노드 거리가 최단 거리일 경우 업데이트
                    if (!visited[v] &amp;&amp; dist[currV] + cost &lt; dist[v]){
                        dist[v] = dist[currV] + cost;
                        queue.add(new Node(v, dist[v]));
                    }
                }
            }
        }
    }
}</code></pre>
<h4 id="백준-1504번-특정한-최단-경로"><a href="https://velog.io/@inss_/BOJ-Gold4-1504%EB%B2%88-%ED%8A%B9%EC%A0%95%ED%95%9C-%EC%B5%9C%EB%8B%A8-%EA%B2%BD%EB%A1%9C">백준 1504번 특정한 최단 경로</a></h4>
]]></description>
        </item>
        <item>
            <title><![CDATA[[SQL] IN, EXISTS 정리]]></title>
            <link>https://velog.io/@inss_/SQL-IN-EXISTS-%EC%A0%95%EB%A6%AC</link>
            <guid>https://velog.io/@inss_/SQL-IN-EXISTS-%EC%A0%95%EB%A6%AC</guid>
            <pubDate>Wed, 02 Jul 2025 14:32:31 GMT</pubDate>
            <description><![CDATA[<h3 id="in">IN</h3>
<ul>
<li>집합 내부에 값이 존재하는지 여부</li>
<li>IN 쿼리 -&gt; 메인 쿼리순서로 진행 </li>
<li>예제 
[STUDENT 테이블][
<img src="https://velog.velcdn.com/images/inss_/post/1f54522e-82e8-41c3-b6f6-7fbd04c5cd4f/image.png" alt=""><pre><code class="language-sql">SELECT *
FROM STUDENT
WHERE department_id IN (&#39;1001&#39;, &#39;1002&#39;);
</code></pre>
</li>
</ul>
<p>// 결과
이름이 홍길동인 row만 출력됨</p>
<pre><code>
&lt;/br&gt;

### NOT IN 
- 조건이나 서브쿼리에 일치하지 않는 값을 반환
- ⭐ 조건에 null이 존재하게 되면 no rows selected로 UNKNOWN(=false) 값이 반환되므로 무조건 null 처리 필요!!!!
- 관련 문제 : [업그레이드 할 수 없는 아이템 구하기](https://school.programmers.co.kr/learn/courses/30/lessons/273712)


&lt;/br&gt;

&lt;/br&gt;

### EXISTS
- 결과로 TRUE, FALSE 반환하는 연산자
- 테이블 간의 결과를 어떤 값이 존재하는 지만 조회할때 사용
- 메인 쿼리 -&gt; EXISTS 쿼리 순서로 진행
=&gt; 메인 쿼리에 먼저 접근 후 ROW 하나 가져오고 EXISTS 서브쿼리를 실행시켜 결과 판단
- 예제
[STUDENT 테이블][
![](https://velog.velcdn.com/images/inss_/post/1f54522e-82e8-41c3-b6f6-7fbd04c5cd4f/image.png)
[DEPARTMENT 테이블]
![](https://velog.velcdn.com/images/inss_/post/6fce73cf-e32d-4a59-aaf9-b3206c68b5dc/image.png)
```SQL
SELECT 
    * 
FROM STUDENT_TABLE A
WHERE 
    EXISTS (SELECT 1
            FROM DEPARTMENT_TABLE B
            WHERE A.department_id = B.department_id)


// 결과
홍길동, 이순신 ROW 출력</code></pre></br>

<h3 id="not-exists">NOT EXISTS</h3>
<ul>
<li>조건에 맞지 않는 ROW 들만 추출할때</li>
</ul>
</br>
</br>

<p>💡 비교</p>
<ul>
<li>EXISTS 절이 성능 더 좋음 </li>
<li>EXISTS는 일치하는 행 발견시 테이블 스캔 중지</li>
<li>IN은 하위 쿼리와 결합하면 서브쿼리를 먼저 처리 한 다음 서브 쿼리 결과를 가지고 메인 쿼리 처리함</li>
<li>EXISTS -&gt; 서브 쿼리에 데이터가 많을 때, IN -&gt; 데이터가 적거나 작은 연산자를 사용할 때</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[SQL] 특정 조건을 만족하는 물고기별 수와 최대 길이 구하기]]></title>
            <link>https://velog.io/@inss_/SQL-%ED%8A%B9%EC%A0%95-%EC%A1%B0%EA%B1%B4%EC%9D%84-%EB%A7%8C%EC%A1%B1%ED%95%98%EB%8A%94-%EB%AC%BC%EA%B3%A0%EA%B8%B0%EB%B3%84-%EC%88%98%EC%99%80-%EC%B5%9C%EB%8C%80-%EA%B8%B8%EC%9D%B4-%EA%B5%AC%ED%95%98%EA%B8%B0</link>
            <guid>https://velog.io/@inss_/SQL-%ED%8A%B9%EC%A0%95-%EC%A1%B0%EA%B1%B4%EC%9D%84-%EB%A7%8C%EC%A1%B1%ED%95%98%EB%8A%94-%EB%AC%BC%EA%B3%A0%EA%B8%B0%EB%B3%84-%EC%88%98%EC%99%80-%EC%B5%9C%EB%8C%80-%EA%B8%B8%EC%9D%B4-%EA%B5%AC%ED%95%98%EA%B8%B0</guid>
            <pubDate>Sat, 28 Jun 2025 16:00:59 GMT</pubDate>
            <description><![CDATA[<h2 id="문제">문제</h2>
<p><a href="https://school.programmers.co.kr/learn/courses/30/lessons/298519">https://school.programmers.co.kr/learn/courses/30/lessons/298519</a></p>
<ul>
<li>처음 풀이</li>
</ul>
<pre><code class="language-sql">SELECT COUNT(*) AS FISH_COUNT, MAX(LENGTH) AS MAX_LENGTH, FISH_TYPE
FROM(
    SELECT ID, FISH_TYPE, IFNULL(LENGTH, 10) AS LENGTH
    FROM FISH_INFO
) AS SUB
GROUP BY FISH_TYPE
HAVING AVG(LENGTH) &gt;= 33
ORDER BY FISH_TYPE ASC</code></pre>
<ul>
<li>두번째 풀이 <ul>
<li>생각해보니 MAX 안에 IFNULL 을 넣으면 된다..<pre><code class="language-sql">SELECT COUNT(*) AS FISH_COUNT, MAX(IFNULL(LENGTH, 10)) AS MAX_LENGTH, FISH_TYPE
FROM FISH_INFO
GROUP BY FISH_TYPE
HAVING AVG(LENGTH) &gt;= 33
ORDER BY FISH_TYPE ASC</code></pre>
</li>
</ul>
</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[프로그래머스] LV1. 크레인 인형뽑기 게임]]></title>
            <link>https://velog.io/@inss_/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-LV1.-%ED%81%AC%EB%A0%88%EC%9D%B8-%EC%9D%B8%ED%98%95%EB%BD%91%EA%B8%B0-%EA%B2%8C%EC%9E%84</link>
            <guid>https://velog.io/@inss_/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-LV1.-%ED%81%AC%EB%A0%88%EC%9D%B8-%EC%9D%B8%ED%98%95%EB%BD%91%EA%B8%B0-%EA%B2%8C%EC%9E%84</guid>
            <pubDate>Sat, 28 Jun 2025 15:34:18 GMT</pubDate>
            <description><![CDATA[<h3 id="💡-풀이">💡 풀이</h3>
<ul>
<li>해당 칸이 0이 아니면 
  -stack이 비어 있지 않고 맨 위의 인형과 같으면 pop 후 +2
  -맨 위의 인형과 다르면 추가 add </li>
<li>인형을 뽑고 0으로 리셋 후 해당 위치는 다 뽑았으므로 break
<del>(😓 처음에 break 깜빡해서 헤맸음)</del></li>
</ul>
<pre><code class="language-java">import java.util.*;

class Solution {
    public int solution(int[][] board, int[] moves) {
        int answer = 0;

        Stack&lt;Integer&gt; stack = new Stack&lt;&gt;();

        int n = board.length;
        for(int move : moves){
            for(int i = 0; i&lt;n; i++){
                int check = board[i][move-1];
                // 해당 칸이 0이 아니면
                if (check != 0) {
                    // stack이 비어 있지 않고 맨 위에 인형이 같으면 pop하고 +2
                    if (!stack.isEmpty() &amp;&amp; stack.peek() == check) {
                        stack.pop();
                        answer+=2;
                    } else {  // 같은 인형이 stack에 없으면 add
                        stack.add(check);
                    }
                    // 인형 뽑기 후 0으로 리셋
                    board[i][move-1] = 0;
                    break;
                }
            }
        }
        return answer;
    }
}</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[[프로그래머스] LV.3 불량 사용자]]></title>
            <link>https://velog.io/@inss_/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-LV.3-%EB%B6%88%EB%9F%89-%EC%82%AC%EC%9A%A9%EC%9E%90</link>
            <guid>https://velog.io/@inss_/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-LV.3-%EB%B6%88%EB%9F%89-%EC%82%AC%EC%9A%A9%EC%9E%90</guid>
            <pubDate>Fri, 27 Jun 2025 16:36:31 GMT</pubDate>
            <description><![CDATA[<h2 id="💡-풀이">💡 풀이</h2>
<h3 id="✔️-순열--treeset">✔️ 순열 + TreeSet</h3>
<ul>
<li>순열 알고리즘으로 id들 중 불량 id 수대로 뽑음</li>
<li>뽑은 id를 불량 id와 매칭</li>
<li>일치하면 treeSet에 담아서 정렬하면서 set으로 저장</li>
<li>뽑은 id가 불량 id와 맞다면 treeSet의 사이즈가 불량 id 수와 같아야함</li>
<li>같으면 hashSet인 answerSet에 treeSet 그대로 넣기 
=&gt; [&quot;frodo&quot;, &quot;crodo&quot;]와 [&quot;crodo&quot;, &quot;frodo&quot;]은 하나로 저장해야하기 때문<pre><code class="language-java">import java.util.*;
</code></pre>
</li>
</ul>
<p>class Solution {
    static Set&lt;TreeSet<String>&gt; answerSet = new HashSet&lt;&gt;();
    public int solution(String[] user_id, String[] banned_id) {
        String[] output = new String[banned_id.length];
        permutation(output, 0, user_id, banned_id, new boolean[user_id.length]);
        return answerSet.size();
    }</p>
<pre><code>// 순열 알고리즘
public void permutation(String[] output, int depth, String[] user_id, String[] banned_id, boolean[] visited){
    if(depth == banned_id.length){
        TreeSet&lt;String&gt; idSet = new TreeSet&lt;&gt;();
        for(int i = 0; i&lt;banned_id.length; i++){
            // 순열로 뽑은 id와 불량 id가 동일한지 확인
            // 동일하면 treeSet에 넣기
            if (check(output[i], banned_id[i])){
                idSet.add(output[i]);
            } 

        }
        // 동일한 id를 담은 idSet의 길이가 불량 id 수와 동일하면 
        // answerSet에 treeMap 형태 그대로
        if (idSet.size() == banned_id.length) {
            answerSet.add(idSet);
        }       
        return;
    }

    for(int i = 0; i&lt;user_id.length; i++){
        if (!visited[i]){
            visited[i] = true;
            output[depth] = user_id[i];
            permutation(output, depth+1, user_id, banned_id, visited);
            visited[i] = false;
        }
    }
}

// 순열로 뽑은 id와 불량 id가 매칭되는지 확인
public boolean check(String output, String banned_id){ 
    if (output.length() != banned_id.length()) return false;
    for(int i = 0; i&lt;output.length(); i++){
        if (banned_id.charAt(i) == &#39;*&#39;) continue;
        if (output.charAt(i) != banned_id.charAt(i)) {
            return false;
        }
    }
    return true;
}</code></pre><p>}</p>
<pre><code>
&lt;/br&gt;
&lt;/br&gt;
🫥 처음에는 조합으로 고르고 어떻게 매칭할지를 계속 고민했음. 그냥 순열로 처음부터 뽑고 그대로 매칭시켜보면 해결됐던 문제!!

&lt;/br&gt;
&lt;/br&gt;

</code></pre>]]></description>
        </item>
        <item>
            <title><![CDATA[[프로그래머스] LV2. 튜플]]></title>
            <link>https://velog.io/@inss_/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-LV2.-%ED%8A%9C%ED%94%8C</link>
            <guid>https://velog.io/@inss_/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-LV2.-%ED%8A%9C%ED%94%8C</guid>
            <pubDate>Wed, 25 Jun 2025 15:06:12 GMT</pubDate>
            <description><![CDATA[<h3 id="💡-풀이">💡 풀이</h3>
<p> ✔️ substring, 정규표현식 기억하기!!!</p>
<ul>
<li>바깥 중괄호 두개 제거 후 &quot;},{&quot; 기준으로 split
-&gt; substring 사용
-&gt; }와 {은 정규표현식 사용
=&gt; ex. {{1,2},{1,2,3}} -&gt; 1,2 / 1,2,3</li>
<li>분리된 튜플 배열에서 튜플 길이 기준으로 오름차순 정렬</li>
<li>튜플 배열 하나씩 &quot;,&quot; 기준으로 분리 후 arrayList에 넣기, 넣을 때 arrayList에 그 값이 포함되어있지 않으면 넣기</li>
<li>ArrayList에서 int 배열로 변환</li>
</ul>
<pre><code class="language-java">import java.util.*;
class Solution {
    public int[] solution(String s) {
        List&lt;Integer&gt; list = new ArrayList&lt;&gt;();

        // 바깥의 중괄호 두개 제거 후 &quot;},{&quot; 기준으로 분리
        String[] tuples = s.substring(2, s.length()-2).split(&quot;\\},\\{&quot;);
        // 분리된 tuple 배열에서 길이 기준으로 오름차순 정렬
        Arrays.sort(tuples, (a, b) -&gt; a.length() - b.length());

        // tuple 배열 하나씩 &quot;,&quot; 기준으로 분리 후 arrayList에 넣기
        for(String tuple : tuples){
            String[] tt = tuple.split(&quot;,&quot;);
            for(String t : tt){
                int num = Integer.parseInt(t);
                if (!list.contains(num)){
                    list.add(num);
                }
            }
        }
        // ArrayList -&gt; int 배열로 변환
        int[] answer = new int[list.size()];
        int idx = 0;
        for(int tuple : list){
            answer[idx++] = tuple;
        }
        return answer;
    }
}</code></pre>
</br>
</br>

<h3 id="🚨-첫번째-실패-코드">🚨 첫번째 실패 코드</h3>
<ul>
<li><p>바깥 중괄호 하나만 제거 후 &quot;,&quot; 기준으로 split
-&gt; 당연히 {1 / 2 / 3} / {4} 이런식으로 분리됨..
-&gt; 원래 생각했던건 {1, 2} / {2} 이렇게 분리된 각 튜플 배열을 또 중괄호 없애고 &quot;,&quot;로 분리하려고 했음
-&gt; 그냥 이런 문자열은 헷갈리니까 적으면서 하자...!!!</p>
<pre><code class="language-java">public int[] solution(String s) {
      List&lt;Integer&gt; list = new ArrayList&lt;&gt;();

      String[] tuples = s.substring(1, s.length()-1).split(&quot;,&quot;);

      // tuple 배열 하나씩 &quot;,&quot; 기준으로 분리 후 arrayList에 넣기
      for(String tuple : tuples){
          String[] tt = tuple.substring(1, s.length()-1).split(&quot;,&quot;);
          for(String t : tt){
              int num = Integer.parseInt(t);

              list.add(num);
              }
          }
      }

     ...
}</code></pre>
</br>
</br>

</li>
</ul>
<h3 id="🚨-두번째-실패-코드">🚨 두번째 실패 코드</h3>
<ul>
<li>각 튜플의 길이대로 정렬을 안하고 하니까 결과 배열 원소값은 똑같은데 순서가 달라서 틀림 </li>
<li>문제를 정확히 이해못해서 이렇게 푼듯.. (똑바로 보잣)
<img src="https://velog.velcdn.com/images/inss_/post/d8c1f635-4153-4b28-851c-3073c3907ff7/image.png" alt=""></li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[프로그래머스] LV3. 다단계 칫솔 판매]]></title>
            <link>https://velog.io/@inss_/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-LV3.-%EB%8B%A4%EB%8B%A8%EA%B3%84-%EC%B9%AB%EC%86%94-%ED%8C%90%EB%A7%A4</link>
            <guid>https://velog.io/@inss_/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-LV3.-%EB%8B%A4%EB%8B%A8%EA%B3%84-%EC%B9%AB%EC%86%94-%ED%8C%90%EB%A7%A4</guid>
            <pubDate>Tue, 24 Jun 2025 14:43:51 GMT</pubDate>
            <description><![CDATA[<h3 id="💡풀이">💡풀이</h3>
<ul>
<li>parent 해시맵에 판매원과 추천인 넣기</li>
<li>seller과 amount 배열 하나씩 계산 함수 실행 (calculate)</li>
<li>해당 판매원의 money 해시에 이익 계산해서 넣기</li>
<li>parent 해시에서 그 판매원의 추천인 찾아서(containsKey) 재귀로 10% 계산 실행</li>
</ul>
<pre><code class="language-java">import java.util.*;

class Solution {
    Map&lt;String, String&gt; parent = new HashMap&lt;&gt;();
    Map&lt;String, Integer&gt; money = new HashMap&lt;&gt;();

    public int[] solution(String[] enroll, String[] referral, String[] seller, int[] amount) {
        // 판매원과 추천인 정보 넣기
        for(int i = 0; i&lt;enroll.length; i++){
            parent.put(enroll[i], referral[i]);
        }

        for(int i = 0; i&lt;seller.length; i++){
            calculate(seller[i], amount[i] * 100);
        }

        int[] answer = new int[enroll.length];
        for(int i = 0; i&lt;enroll.length; i++){
            answer[i] = money.getOrDefault(enroll[i], 0);
        }
        return answer;
    }

    void calculate(String curr, int sales){
        int nextSales = sales / 10;
        money.put(curr, money.getOrDefault(curr, 0) + sales - nextSales);

        if(nextSales &gt; 0 &amp;&amp; parent.containsKey(curr)){
            calculate(parent.get(curr), nextSales);
        }
    }
}</code></pre>
</br>
</br>
🫥 처음에는 트리로 풀어야하나 했는데 이진트리는 아니여서 계속 고민하다가 참고한 풀이 (재귀는 생각못했네..)]]></description>
        </item>
        <item>
            <title><![CDATA[[프로그래머스] LV2. 도넛과 막대 그래프]]></title>
            <link>https://velog.io/@inss_/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-LV2.-%EB%8F%84%EB%84%9B%EA%B3%BC-%EB%A7%89%EB%8C%80-%EA%B7%B8%EB%9E%98%ED%94%84</link>
            <guid>https://velog.io/@inss_/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-LV2.-%EB%8F%84%EB%84%9B%EA%B3%BC-%EB%A7%89%EB%8C%80-%EA%B7%B8%EB%9E%98%ED%94%84</guid>
            <pubDate>Sat, 21 Jun 2025 15:45:01 GMT</pubDate>
            <description><![CDATA[<h3 id="💡-풀이">💡 풀이</h3>
<p>🫥 문제가 어려워서 다른 사람 풀이 참고했는데 생각보다 쉬웠던 문제</p>
<ul>
<li>생성된 정점과 각 그래프의 특징을 찾으면 되는 문제</li>
<li>생성된 정점 : in은 무조건 0, out은 2개 이상</li>
<li>막대 모양 그래프 : out이 0인 정점이 있음 (마지막 정점)</li>
<li>8자 모양 그래프 : out이 2개 이상인 정점중에 in이 존재하는 정점</li>
<li>도넛 모양 그래프 : 생성된 정점의 out 간선 수 - 막대 그래프 - 8자 그래프</li>
<li>각 정점의 in과 out 간선 수를 각각 hashMap에 넣고 조건에 맞게 생성된 정점과 그래프 수 찾으면 됨</li>
</ul>
<pre><code class="language-java">import java.util.*;

class Solution {
    public int[] solution(int[][] edges) {
        int[] result = new int[4];
        HashMap&lt;Integer, Integer&gt; in = new HashMap&lt;&gt;();
        HashMap&lt;Integer, Integer&gt; out = new HashMap&lt;&gt;();

        // 각 정점마다 in 간선과 out 간선 count 
        for(int[] edge : edges){ // a -&gt; b
            int a = edge[0];
            int b = edge[1];
            in.put(b, in.getOrDefault(b, 0) + 1);
            out.put(a, out.getOrDefault(a, 0) + 1);
        }


        for(int o : out.keySet()){
            if (out.get(o) &gt;= 2){
                // 생성된 정점 찾기
                if (!in.containsKey(o)){
                    result[0] = o;
                 } else { // 8자 모양 그래프 찾기
                    result[3] += 1;
                }
            }

        }
        // 막대 모양 그래프 찾기
        for(int i : in.keySet()){
            if (!out.containsKey(i)) result[2] += 1;
        }

        result[1] = out.get(result[0]) - result[2] - result[3];

        return result;
    }
}</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[[프로그래머스] LV2. 전력망을 둘로 나누기]]></title>
            <link>https://velog.io/@inss_/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-%EC%A0%84%EB%A0%A5%EB%A7%9D%EC%9D%84-%EB%91%98%EB%A1%9C-%EB%82%98%EB%88%84%EA%B8%B0</link>
            <guid>https://velog.io/@inss_/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-%EC%A0%84%EB%A0%A5%EB%A7%9D%EC%9D%84-%EB%91%98%EB%A1%9C-%EB%82%98%EB%88%84%EA%B8%B0</guid>
            <pubDate>Fri, 20 Jun 2025 08:55:03 GMT</pubDate>
            <description><![CDATA[<h3 id="💡-풀이">💡 풀이</h3>
<ul>
<li>끊을 전선 하나씩 고르고 그 전선 제외하고 인접 리스트 생성(createList)</li>
<li>생성 후 인접 리스트에 전선 정보 넣기 -&gt; bfs 실행</li>
<li>bfs 실행해서 노드 수 count하고 두 전력망의 송전탑 개수 차이를 반환</li>
<li>가장 작은 차이가 정답<pre><code class="language-java">import java.util.*;
</code></pre>
</li>
</ul>
<p>class Solution {
    static ArrayList&lt;ArrayList<Integer>&gt; graph;
    public int solution(int n, int[][] wires) {
        int answer = Integer.MAX_VALUE;
        for(int i = 0; i&lt;wires.length; i++){
            createList(n);</p>
<pre><code>        // 해당 전선(wires[i]) 제외하고 인접 리스트에 넣기
        for(int j = 0; j&lt;wires.length; j++){
            if (j == i) continue;
            int[] curr = wires[j];
            graph.get(curr[0]).add(curr[1]);
            graph.get(curr[1]).add(curr[0]);
        }
        // bfs 실행
        answer = Math.min(checkBfs(n), answer);
    }
    return answer;
}

// 인접 리스트 생성
public void createList(int n){
    graph = new ArrayList&lt;&gt;();
    for(int i = 0; i&lt;=n; i++){
        graph.add(new ArrayList&lt;&gt;());
    }
}

public int checkBfs(int n){
    int cnt = 1;
    Queue&lt;Integer&gt; q = new LinkedList&lt;&gt;();
    boolean[] visited = new boolean[n+1];

    q.add(1);
    visited[1] = true;

    while(!q.isEmpty()){
        int curr = q.poll();
        for(int i : graph.get(curr)){
            if(!visited[i]){
                q.add(i);
                visited[i] = true;
                cnt++;
            }
        }
    }
    // cnt : bfs로 찾은 노드 count 
    // 두 전력망 차이 반환
    return Math.abs(2 * cnt - n);
}</code></pre><p>}
```</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[BOJ-Gold4] 14502번 연구소]]></title>
            <link>https://velog.io/@inss_/BOJ-Gold4-14502%EB%B2%88-%EC%97%B0%EA%B5%AC%EC%86%8C</link>
            <guid>https://velog.io/@inss_/BOJ-Gold4-14502%EB%B2%88-%EC%97%B0%EA%B5%AC%EC%86%8C</guid>
            <pubDate>Mon, 16 Jun 2025 16:16:52 GMT</pubDate>
            <description><![CDATA[<h2 id="💡-풀이">💡 풀이</h2>
<h3 id="✔️-조합--bfs">✔️ 조합 + BFS</h3>
<ul>
<li>조합 알고리즘으로 빈칸 중 벽 세울 곳 3군데 구하기</li>
<li>빈칸 3곳을 골랐으면 bfs 실행</li>
<li>나중에 arr 원상복구 시키기 위해 바이러스 감염된 곳은 따로 좌표 보관(newVirus)</li>
<li>빈칸 수 count</li>
<li>바이러스 새롭게 감염된 곳 다시 빈칸으로 복구<pre><code class="language-java">import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Queue;
import java.util.StringTokenizer;
</code></pre>
</li>
</ul>
<p>public class Main {
    static int n, m;
    static int[][] arr;
    static Queue&lt;int[]&gt; q = new LinkedList&lt;&gt;();
    static int[] dx = {1, -1, 0, 0};
    static int[] dy = {0, 0, 1, -1};
    static int result = 0;</p>
<pre><code>public static void main(String[] args) throws IOException {
    BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
    StringTokenizer st = new StringTokenizer(br.readLine());
    n = Integer.parseInt(st.nextToken());
    m = Integer.parseInt(st.nextToken());
    arr = new int[n][m];
    for(int i = 0; i&lt;n; i++){
        st = new StringTokenizer(br.readLine());
        for(int j = 0; j&lt;m; j++){
            arr[i][j] = Integer.parseInt(st.nextToken());
        }
    }
    combination(0, 0);
    System.out.println(result);
}

public static void combination(int start, int depth){
    // 조합 알고리즘으로 빈칸 중에 3곳 벽으로 처리하고 bfs 실행
    if (depth == 3){
        result = Math.max(result, bfs());
        return;
    }

    for(int i = start; i&lt;n*m; i++){
        int x = i / m;
        int y = i % m;

        if (arr[x][y] != 0) continue;

        arr[x][y] = 1;
        combination(i+1, depth+1);
        arr[x][y] = 0;
    }
}

public static int bfs(){
    int cnt = 0;
    List&lt;int[]&gt; newVirus = new ArrayList&lt;&gt;(); // 바이러스 감염된 좌표 저장 -&gt; 원상복구때 필요
    // bfs 실행
    for(int i = 0; i&lt;n; i++){
        for(int j = 0; j&lt;m; j++){
            if (arr[i][j] == 2){
                q.add(new int[]{i, j});
            }
        }
    }

    while(!q.isEmpty()){
        int[] curr = q.poll();
        for(int i = 0; i&lt;4; i++){
            int nx = curr[0] + dx[i];
            int ny = curr[1] + dy[i];

            if (nx &gt;= 0 &amp;&amp; nx &lt; n &amp;&amp; ny &gt;= 0 &amp;&amp; ny &lt; m){
                if (arr[nx][ny] == 0){
                    arr[nx][ny] = 2;
                    q.add(new int[]{nx, ny});
                    newVirus.add(new int[]{nx, ny});
                }
            }
        }
    }

    // 빈칸 count
    for(int i = 0; i&lt;n; i++){
        for(int j = 0; j&lt;m; j++){
            if (arr[i][j] == 0){
                cnt++;
            }
        }
    }
    // 바이러스 감염된 곳 다시 빈칸으로 원상복구
    for(int[] v : newVirus){
        arr[v[0]][v[1]] = 0;
    }
    return cnt;
}</code></pre><p>}
```</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[BOJ-Silver1] 1946번 신입 사원]]></title>
            <link>https://velog.io/@inss_/BOJ-Silver1-1946%EB%B2%88-%EC%8B%A0%EC%9E%85-%EC%82%AC%EC%9B%90</link>
            <guid>https://velog.io/@inss_/BOJ-Silver1-1946%EB%B2%88-%EC%8B%A0%EC%9E%85-%EC%82%AC%EC%9B%90</guid>
            <pubDate>Mon, 16 Jun 2025 15:19:43 GMT</pubDate>
            <description><![CDATA[<h3 id="💡풀이">💡풀이</h3>
<ul>
<li>서류 순위 기준으로 오름차순</li>
<li>맨 앞에 있는 사람은 무조건 채용</li>
<li>두번째 사람부터 면접 순위가 앞사람들보다 높은지 확인<pre><code class="language-java">import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Arrays;
import java.util.StringTokenizer;
</code></pre>
</li>
</ul>
<p>public class Main {
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        int T = Integer.parseInt(br.readLine());
        for(int  t= 0; t&lt;T; t++){
            int n = Integer.parseInt(br.readLine());
            int[][] scores = new int[n][2];
            // 순위 입력
            for(int i = 0; i&lt;n; i++){
                StringTokenizer st = new StringTokenizer(br.readLine());
                scores[i][0] = Integer.parseInt(st.nextToken());
                scores[i][1] = Integer.parseInt(st.nextToken());
            }</p>
<pre><code>        int result = 1;
        // 서류 성적 순위 기준으로 오름차순
        Arrays.sort(scores, (a, b) -&gt; Integer.compare(a[0], b[0]));
        int prevMin = scores[0][1];
        // 앞에 면접 순위 중 가장 작은 순위랑 비교해서 작으면 result +1
        for(int i = 1; i&lt;n; i++){
            if (prevMin &gt; scores[i][1]) {
                result++;
                prevMin = scores[i][1];
            }
        }
        System.out.println(result);
    }
}</code></pre><p>}</p>
<pre><code>
&lt;/br&gt;
&lt;/br&gt;

###  🚨시간초과
- 면접 순위 확인하는 코드에서 이중 for문으로 시간초과
- 앞에 사람들을 하나씩 확인하는게 아니라 앞 사람들 중 높은 순위를 계속 갱신하고 그걸 기준으로 확인
```java
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Arrays;
import java.util.StringTokenizer;

public class Main {
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        int T = Integer.parseInt(br.readLine());
        for(int  t= 0; t&lt;T; t++){
            int n = Integer.parseInt(br.readLine());
            int[][] scores = new int[n][2];
            for(int i = 0; i&lt;n; i++){
                StringTokenizer st = new StringTokenizer(br.readLine());
                scores[i][0] = Integer.parseInt(st.nextToken());
                scores[i][1] = Integer.parseInt(st.nextToken());
            }

            int result = 1;
            Arrays.sort(scores, (a, b) -&gt; Integer.compare(a[0], b[0]));
            for(int i = 1; i&lt;n; i++){
                int cnt = 0;
                for(int j = i-1; j&gt;=0; j--){
                    if (scores[i][1] &lt; scores[j][1]) cnt++;
                }
                if (cnt == i) result++;
            }
            System.out.println(result);
        }

    }
}</code></pre>]]></description>
        </item>
    </channel>
</rss>