<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>yuki.log</title>
        <link>https://velog.io/</link>
        <description></description>
        <lastBuildDate>Mon, 06 Feb 2023 15:58:24 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <copyright>Copyright (C) 2019. yuki.log. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/yuki-kim" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[[백준] 2501 약수 구하기 - Java]]></title>
            <link>https://velog.io/@yuki-kim/%EB%B0%B1%EC%A4%80-2501-%EC%95%BD%EC%88%98-%EA%B5%AC%ED%95%98%EA%B8%B0-Java</link>
            <guid>https://velog.io/@yuki-kim/%EB%B0%B1%EC%A4%80-2501-%EC%95%BD%EC%88%98-%EA%B5%AC%ED%95%98%EA%B8%B0-Java</guid>
            <pubDate>Mon, 06 Feb 2023 15:58:24 GMT</pubDate>
            <description><![CDATA[<h3 id="문제">문제</h3>
<p><img src="https://velog.velcdn.com/images/yuki-kim/post/bfeeda76-2233-4bf5-b7a1-bb45aa20ac4a/image.png" alt="">
<a href="https://www.acmicpc.net/problem/2501">링크</a></p>
<hr>
<h3 id="코드">코드</h3>
<pre><code class="language-java">import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.StringTokenizer;

public class Main {
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer st = new StringTokenizer(br.readLine());

        int number = Integer.parseInt(st.nextToken());
        int index = Integer.parseInt(st.nextToken()) - 1;

        List&lt;Integer&gt; list = new ArrayList&lt;&gt;();
        for (int i = 1; i &lt;= Math.sqrt(number); i++) {
            if (number % i == 0) {
                list.add(i);
                if (number / i != i) list.add(number / i);
            }
        }
        Collections.sort(list);

        System.out.println(list.size() &gt; index ? list.get(index) : &quot;0&quot;);
    }
}</code></pre>
<hr>
<h3 id="리뷰">리뷰</h3>
<p><img src="https://velog.velcdn.com/images/yuki-kim/post/aff764a0-cc21-4453-a70e-028f8ab58970/image.png" alt=""></p>
<p>약수를 구한 뒤 약수 중 <code>K</code>번 째 작은수를 출력하는 문제이다.</p>
<p>약수는 기존처럼 제곱근을 이용해 구해주었다.
그리고 오름차순으로 정렬한 뒤에 <code>K</code>번째 작은 수는 인덱스 상에서는 <code>K-1</code> 번인것을 고려하여 리스트의 사이즈와 비교한 뒤 적절한 값을 출력하도록 하는 문제이다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[백준] 20053 최소, 최대 2 - Java]]></title>
            <link>https://velog.io/@yuki-kim/%EB%B0%B1%EC%A4%80-20053-%EC%B5%9C%EC%86%8C-%EC%B5%9C%EB%8C%80-2-Java</link>
            <guid>https://velog.io/@yuki-kim/%EB%B0%B1%EC%A4%80-20053-%EC%B5%9C%EC%86%8C-%EC%B5%9C%EB%8C%80-2-Java</guid>
            <pubDate>Mon, 06 Feb 2023 11:54:36 GMT</pubDate>
            <description><![CDATA[<h3 id="문제">문제</h3>
<p><img src="https://velog.velcdn.com/images/yuki-kim/post/9f80dc23-7bed-48e3-863f-3d8bc6a3a179/image.png" alt="">
<a href="https://www.acmicpc.net/problem/20053">링크</a></p>
<hr>
<h3 id="코드">코드</h3>
<pre><code class="language-java">import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;

public class Main {
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringBuilder sb = new StringBuilder();

        int T = Integer.parseInt(br.readLine());
        for (int i = 0; i &lt; T; i++) {
            int N = Integer.parseInt(br.readLine());

            int min = Integer.MAX_VALUE;
            int max = Integer.MIN_VALUE;
            StringTokenizer st = new StringTokenizer(br.readLine());
            for (int j = 0; j &lt; N; j++) {
                int num = Integer.parseInt(st.nextToken());
                if (num &lt; min) min = num;
                if (num &gt; max) max = num;
            }
            sb.append(min).append(&quot; &quot;).append(max).append(&quot;\n&quot;);
        }
        System.out.print(sb);
        br.close();
    }
}</code></pre>
<hr>
<h3 id="리뷰">리뷰</h3>
<p><img src="https://velog.velcdn.com/images/yuki-kim/post/318cbef1-5e06-482d-8de3-f8e4bae6291b/image.png" alt=""></p>
<p>첫번째 풀이는 생략하였지만 배열로 입력받아 <code>Arrays.sort</code>를 이용하여 정렬을 통해 최소, 최댓값을 구하였지만 생각보다 시간이 엄청높게나왔다.</p>
<p>그래서 그냥 값을 입력받을 때마다 바로바로 비교하는 방식으로 바꾸어 제출하니 시간이 확줄긴했다.</p>
<p>배열 정렬의 경우 최악의 경우 O(N^2)의 시간복잡도를 가지게되지만
바로 비교하는 경우 O(N)이라 시간차이가 꽤나게된다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[프로그래머스] 문자열 내 p와 y의 개수 - Java]]></title>
            <link>https://velog.io/@yuki-kim/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-%EB%AC%B8%EC%9E%90%EC%97%B4-%EB%82%B4-p%EC%99%80-y%EC%9D%98-%EA%B0%9C%EC%88%98-Java</link>
            <guid>https://velog.io/@yuki-kim/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-%EB%AC%B8%EC%9E%90%EC%97%B4-%EB%82%B4-p%EC%99%80-y%EC%9D%98-%EA%B0%9C%EC%88%98-Java</guid>
            <pubDate>Fri, 03 Feb 2023 04:11:15 GMT</pubDate>
            <description><![CDATA[<h3 id="문제">문제</h3>
<p><img src="https://velog.velcdn.com/images/yuki-kim/post/f6eb280f-c989-461a-ad48-892087367ec8/image.png" alt="">
<a href="https://school.programmers.co.kr/learn/courses/30/lessons/12916">링크</a></p>
<hr>
<h3 id="코드">코드</h3>
<pre><code class="language-java">class Solution {
    boolean solution(String s) {
        boolean answer = true;
        int pCount = 0;
        int yCount = 0;

        s = s.toLowerCase();

        for (int i = 0; i &lt; s.length(); i++) {
            if (s.charAt(i) == &#39;p&#39;) pCount++;
            else if (s.charAt(i) == &#39;y&#39;) yCount++;
        }
        if (pCount != yCount) answer = false;

        return answer;
    }
}</code></pre>
<hr>
<h3 id="리뷰">리뷰</h3>
<p><img src="https://velog.velcdn.com/images/yuki-kim/post/f375613c-6c39-4e47-a5e0-0a79035bd34f/image.png" alt=""></p>
<p>정말 예전에 풀었던 문제인데 리뷰 작성을 안한것을 이제야 알았다.
코드를 새로 고친 것도 아니여서 올리지 말까 고민하다가 그래도 여태 푼 문제들을 올렸는데 몇개만 빼먹고 올리자니 신경쓰여서 올리게되었다 😅</p>
<p>그리고 최근에 JPA 공부에 집중하다보니 알고리즘 문제를 거의 풀지못해서 새롭게 느껴졌는데 큰일이다 🥲</p>
<p>문제 풀이 접근방식은 결국 대문자이든 소문자이든 <code>p</code>와 <code>y</code>의 개수를 세는 것이 핵심이므로 소문자로 통합하여 문자열을 한 글자씩 읽어 두 글자의 카운트를 비교하는 방식으로 접근하였다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[백준] 12891 DNA 비밀번호 - Java]]></title>
            <link>https://velog.io/@yuki-kim/%EB%B0%B1%EC%A4%80-12891-DNA-%EB%B9%84%EB%B0%80%EB%B2%88%ED%98%B8-Java</link>
            <guid>https://velog.io/@yuki-kim/%EB%B0%B1%EC%A4%80-12891-DNA-%EB%B9%84%EB%B0%80%EB%B2%88%ED%98%B8-Java</guid>
            <pubDate>Tue, 17 Jan 2023 04:51:16 GMT</pubDate>
            <description><![CDATA[<h3 id="문제">문제</h3>
<p><img src="https://velog.velcdn.com/images/yuki-kim/post/ede06672-b8f8-4d99-9276-fc0c13670ac0/image.png" alt="">
<a href="https://www.acmicpc.net/problem/12891">링크</a></p>
<hr>
<h3 id="코드">코드</h3>
<pre><code class="language-java">import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;

public class Main {

    static int[] inputCheckArr = new int[4];
    static int[] checkArr = new int[4];
    static int checkCount;

    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer st = new StringTokenizer(br.readLine());
        int S = Integer.parseInt(st.nextToken());
        int P = Integer.parseInt(st.nextToken());
        char[] inputArr = br.readLine().toCharArray();

        checkCount = 0;
        st = new StringTokenizer(br.readLine());
        for (int i = 0; i &lt; 4; i++) {
            checkArr[i] = Integer.parseInt(st.nextToken());

            if (checkArr[i] == 0) checkCount++;
        }
        br.close();

        int resultCount = 0;
        for (int i = 0; i &lt; P; i++) {
            add(inputArr[i]);
        }
        if (checkCount == 4) resultCount++;

        for (int i = P; i &lt; S; i++) {
            int j = i - P;
            add(inputArr[i]);
            remove(inputArr[j]);

            if (checkCount == 4) resultCount++;
        }
        System.out.println(resultCount);
    }

    private static void add(char value) {
        switch (value) {
            case &#39;A&#39;:
                inputCheckArr[0]++;
                if (inputCheckArr[0] == checkArr[0]) checkCount++;
                break;

            case &#39;C&#39;:
                inputCheckArr[1]++;
                if (inputCheckArr[1] == checkArr[1]) checkCount++;
                break;

            case &#39;G&#39;:
                inputCheckArr[2]++;
                if (inputCheckArr[2] == checkArr[2]) checkCount++;
                break;

            case &#39;T&#39;:
                inputCheckArr[3]++;
                if (inputCheckArr[3] == checkArr[3]) checkCount++;
                break;
        }
    }

    private static void remove(char value) {
        switch (value) {
            case &#39;A&#39;:
                if (inputCheckArr[0] == checkArr[0]) checkCount--;
                inputCheckArr[0]--;
                break;

            case &#39;C&#39;:
                if (inputCheckArr[1] == checkArr[1]) checkCount--;
                inputCheckArr[1]--;
                break;

            case &#39;G&#39;:
                if (inputCheckArr[2] == checkArr[2]) checkCount--;
                inputCheckArr[2]--;
                break;

            case &#39;T&#39;:
                if (inputCheckArr[3] == checkArr[3]) checkCount--;
                inputCheckArr[3]--;
                break;
        }
    }
}</code></pre>
<hr>
<h3 id="리뷰">리뷰</h3>
<p><img src="https://velog.velcdn.com/images/yuki-kim/post/5a59f757-abd6-4354-9db2-4b842ed12a66/image.png" alt=""></p>
<p>슬라이딩 윈도우 알고리즘을 이용한 문제이다.
슬라이딩 윈도우는 투 포인터와 매우 유사하다.
오히려 같은 크기로 이동하다보니 조금 더 편한 것 같기도하다 😛</p>
<p>입력받은 문자열을 배열로받고 비밀번호 조건 배열과 매칭할 수 있게 입력 문자열 배열을 순차로돌며 비밀번호 조건 배열과 같은 순서로 각각의 자리에 카운트하여 조건을 만족하는지 판단하는 방식으로 구현하였다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[백준] 1253 좋다 - Java]]></title>
            <link>https://velog.io/@yuki-kim/%EB%B0%B1%EC%A4%80-1253-%EC%A2%8B%EB%8B%A4-Java</link>
            <guid>https://velog.io/@yuki-kim/%EB%B0%B1%EC%A4%80-1253-%EC%A2%8B%EB%8B%A4-Java</guid>
            <pubDate>Mon, 16 Jan 2023 05:29:08 GMT</pubDate>
            <description><![CDATA[<h3 id="문제">문제</h3>
<p><img src="https://velog.velcdn.com/images/yuki-kim/post/cd381ccd-ea7d-4f86-ab13-e60b9a124bfc/image.png" alt="">
<a href="https://www.acmicpc.net/problem/1253">링크</a></p>
<hr>
<h3 id="코드">코드</h3>
<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;

public class Main {
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        int N = Integer.parseInt(br.readLine());
        int[] numberArray = new int[N];

        StringTokenizer st = new StringTokenizer(br.readLine());
        for (int i = 0; i &lt; numberArray.length; i++) {
            numberArray[i] = Integer.parseInt(st.nextToken());
        }
        br.close();
        Arrays.sort(numberArray);

        int count = 0;
        for (int k = 0; k &lt; numberArray.length; k++) {
            long findNumber = numberArray[k];
            int pointerI = 0;
            int pointerJ = numberArray.length - 1;
            while (pointerI &lt; pointerJ) {
                if (numberArray[pointerI] + numberArray[pointerJ] == findNumber) {
                    if (pointerI != k &amp;&amp; pointerJ != k) {
                        count++;
                        break;
                    } else if (pointerI == k) pointerI++;
                    else pointerJ--;

                } else if (numberArray[pointerI] + numberArray[pointerJ] &gt; findNumber) pointerJ--;
                else pointerI++;
            }
        }
        System.out.println(count);
    }
}</code></pre>
<hr>
<h3 id="리뷰">리뷰</h3>
<p><img src="https://velog.velcdn.com/images/yuki-kim/post/c943b65c-1d08-4f75-b104-0305f72fd3bc/image.png" alt=""></p>
<p>주어진 모든 입력에대해 좋은 수인지 판별해야하기 때문에 O(N^2)의 시간복잡도로 문제를 풀게되면 총 O(N^3)이 되어 실패하게된다.</p>
<p>다른 투포인터 문제와 방식은 동일하게 진행된다.
다만 유의해야 할점은 입력되는 수가 <code>정수</code>라는 점을 고려해야 한다.</p>
<p>만약 5가 좋은 수인지 확인하려는데 5와 0을 가리키면 5 + 0 = 5니까 좋은 수라고되면 안되기 때문에 우리가 좋은 수인지 찾을 때 그 숫자 자기자신이 계산에 포함되면 안되는 예외조건이 필요하다.</p>
<p>그래서 두 인덱스의 값의 합이 우리가 찾는 수 일 때 각각의 두 수가 그 수인지 확인하는 작업이 필요하다.
이 부분에서 실수를해서 시간초과가 되었는데 두 수가 찾는 수가 아닌지 판별하는 동시에 만약 가리키는 숫자가 찾는 수였으면 어떻게 해야할지 정해주어야한다.
까먹고 if문을 하나만 두었더니 거기에 갇혀서 나오지못해 시간초과 오류가 발생했다. 😨</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[백준] 1940 주몽 - Java]]></title>
            <link>https://velog.io/@yuki-kim/%EB%B0%B1%EC%A4%80-1940-%EC%A3%BC%EB%AA%BD-Java</link>
            <guid>https://velog.io/@yuki-kim/%EB%B0%B1%EC%A4%80-1940-%EC%A3%BC%EB%AA%BD-Java</guid>
            <pubDate>Mon, 16 Jan 2023 05:12:50 GMT</pubDate>
            <description><![CDATA[<h3 id="문제">문제</h3>
<p><img src="https://velog.velcdn.com/images/yuki-kim/post/a9bf2eec-8595-4823-81fa-bab5e7a9134b/image.png" alt="">
<a href="https://www.acmicpc.net/problem/1940">링크</a></p>
<hr>
<h3 id="코드">코드</h3>
<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;

public class Main {
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        int N = Integer.parseInt(br.readLine());
        int M = Integer.parseInt(br.readLine());
        int[] serialArray = new int[N];

        StringTokenizer st = new StringTokenizer(br.readLine());
        for (int i = 0; i &lt; N; i++) {
            serialArray[i] = Integer.parseInt(st.nextToken());
        }
        br.close();
        Arrays.sort(serialArray);

        int pointerI = 0;
        int pointerJ = serialArray.length - 1;
        int count = 0;
        while (pointerJ &gt; pointerI) {
            if (serialArray[pointerI] + serialArray[pointerJ] == M) {
                count++;
                pointerI++;
                pointerJ--;
            } else if (serialArray[pointerI] + serialArray[pointerJ] &gt; M) pointerJ--;
            else pointerI++;
        }
        System.out.println(count);
    }
}</code></pre>
<hr>
<h3 id="리뷰">리뷰</h3>
<p><img src="https://velog.velcdn.com/images/yuki-kim/post/c9f112e8-d6fe-441c-82d1-d4cc53243a25/image.png" alt=""></p>
<p>투포인터를 이용해 양 끝에서 시작해서 주어진 숫자의 합이 나오도록 포인터를 이동하여 count한다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[백준] 2018 수들의 합 5 - Java]]></title>
            <link>https://velog.io/@yuki-kim/%EB%B0%B1%EC%A4%80-2018-%EC%88%98%EB%93%A4%EC%9D%98-%ED%95%A9-5-Java</link>
            <guid>https://velog.io/@yuki-kim/%EB%B0%B1%EC%A4%80-2018-%EC%88%98%EB%93%A4%EC%9D%98-%ED%95%A9-5-Java</guid>
            <pubDate>Sun, 15 Jan 2023 12:33:06 GMT</pubDate>
            <description><![CDATA[<h3 id="문제">문제</h3>
<p><img src="https://velog.velcdn.com/images/yuki-kim/post/f42b7b58-d975-419e-b53a-d4723746b347/image.png" alt="">
<a href="https://www.acmicpc.net/problem/2018">링크</a></p>
<hr>
<h3 id="코드">코드</h3>
<pre><code class="language-java">import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class Main {
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        int N = Integer.parseInt(br.readLine());
        int startIndex = 1;
        int endIndex = 1;
        int sum = 1;
        int count = 1;

        while (endIndex != N) {
            if (sum == N) {
                endIndex++;
                sum += endIndex;
                count++;
            } else if (sum &gt; N) {
                sum -= startIndex;
                startIndex++;
            } else {
                endIndex++;
                sum += endIndex;
            }
        }
        System.out.println(count);
    }
}</code></pre>
<hr>
<h3 id="리뷰">리뷰</h3>
<p><img src="https://velog.velcdn.com/images/yuki-kim/post/b05c9ec7-de25-4402-bfb6-92b372748a13/image.png" alt=""></p>
<p>투 포인터 알고리즘을 이용한 문제풀이이다.
N값의 범위가 최대 천만으로 O(N)의 시간복잡도를 가지는 방법으로 문제를 해결해야한다.</p>
<p>연속된 숫자의 합이 나타나는 가짓수를 구하는 문제로 <code>startIndex</code>와 <code>endIndex</code> 값을 이용해 배열을 순차적으로 진행하며 연속되는 숫자의 합이 주어진 숫자와 같아지는 경우 count한다.</p>
<p>생각보다 고급스러운? 알고리즘 이름에 어딘가 되게 단순해 보이는 코드이다.</p>
<p>아직은 알고리즘을 막 공부하기 시작해서 그런지 처음 백준, 프로그래머스 문제를 풀었었던 기분이 다시 느껴진다.</p>
<p>다양한 알고리즘을 배워나가는데에 설레기도 하는데 이 많은 애들을 다 이해하고 평소에 문제를 보면 이건 어떠한 알고리즘 문제로 풀면 되겠다 하는 느낌이 올 수 있나 싶은 불안감도 드는 것 같다 😬</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[백준] 10986 나머지 합 - Java]]></title>
            <link>https://velog.io/@yuki-kim/%EB%B0%B1%EC%A4%80-10986-%EB%82%98%EB%A8%B8%EC%A7%80-%ED%95%A9-Java</link>
            <guid>https://velog.io/@yuki-kim/%EB%B0%B1%EC%A4%80-10986-%EB%82%98%EB%A8%B8%EC%A7%80-%ED%95%A9-Java</guid>
            <pubDate>Sun, 15 Jan 2023 11:26:07 GMT</pubDate>
            <description><![CDATA[<h3 id="문제">문제</h3>
<p><img src="https://velog.velcdn.com/images/yuki-kim/post/a62c6047-152c-4289-9f8b-edaa12f46724/image.png" alt="">
<a href="https://www.acmicpc.net/problem/10986">링크</a></p>
<hr>
<h3 id="코드">코드</h3>
<pre><code class="language-java">import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.*;

public class Main {
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer st = new StringTokenizer(br.readLine());
        int N = Integer.parseInt(st.nextToken());
        int M = Integer.parseInt(st.nextToken());
        long[] sumArray = new long[N];
        long[] remainderArray = new long[M];
        long count = 0;

        st = new StringTokenizer(br.readLine());
        sumArray[0] = Integer.parseInt(st.nextToken());
        for (int i = 1; i &lt; sumArray.length; i++) {
            sumArray[i] = sumArray[i - 1] + Integer.parseInt(st.nextToken());
        }

        for (long value : sumArray) {
            int remainder = (int) (value % M);

            if (remainder == 0) count++;
            remainderArray[remainder]++;
        }

        for (long value : remainderArray) {
            if (value &gt; 1) count += (value * (value - 1)) / 2;
        }
        System.out.println(count);
    }
}</code></pre>
<hr>
<h3 id="리뷰">리뷰</h3>
<p><img src="https://velog.velcdn.com/images/yuki-kim/post/6d601a25-e271-4ad8-933a-5989131b0c77/image.png" alt=""></p>
<p>인생 첫 골드문제이다 😤
이전에 풀었던 구간합 알고리즘을 활용하여 푸는 문제이다.</p>
<p>문제에서 원하는 결과는 무엇을 뜻하는 걸까?
배열의 구간합이 M으로 나누어 떨어지는 i, j쌍의 개수란</p>
<p>1 2 3 1 2 라는 값이 있을 때
어디서부터 어디까지 더하면 3으로 나누어 떨어질까?
1번부터 5번까지라고 가정하면</p>
<p>1번+2번, 1번+2번+3번, 1번+2번+3번+4번+5번,
2번+3번+4번,
3번, 3번+4번+5번,
4번+5번</p>
<p>이렇게 7가지나되는 구간이 나온다.
(골드부터는 문제를 이해하는 것도 일인건가 😞)</p>
<p>여기서 곱셈공식처럼 한 가지 법칙이있다.</p>
<p>각 수의 나머지를 구하고 그 둘을 더해 다시 나머지를 구한 것과
각 수를 더하고 더한 수의 나머지를 구한 값은 같다는 것이다.
식만 봐서는 이해가 안가서 예시를 들어보면</p>
<p>1과 2가 있고 숫자 3으로 이를 나눈다고 생각해보자
1을 3으로 나눈 나머지는 1, 2를 3으로 나눈 나머지는 2이고 이 나머지들의 합은 1 + 2 = 3이다. 이 나머지의 합을 3으로 나눈 나머지는 0이다.</p>
<p>다음 방법인 1과 2를 우선 더하면 3이다. 이를 3으로 나눈 나머지는 0이다.
즉 나머지를 구하고 구하고 더하고 구하는 4번의 계산이 더하고 구하는 2번의 계산으로도 같은 결과를 얻는다.</p>
<p>이러한 특성을 이용하여 푸는게 이번 문제의 핵심이다.
즉 구간합 배열을 주어진 수로 나눈 나머지의 결과값을 저장한 배열을 이용하면 간단하게 문제를 해결할 수 있다.</p>
<p>나누는 수 : 3
<code>1 2 3 1 2</code> - 입력 배열
<code>1 3 6 7 9</code> - 구간합 배열
<code>1 0 0 1 0</code> - 구간합을 주어진 수로 나눈 나머지배열</p>
<p>나머지 배열이 0인 곳은 구간합이 나누어 떨어진다는 것이므로 0의 갯수인 3개가 결과값에 포함된다.</p>
<p>그리고 기존의 구간합 원리를 생각해보면 같은 나머지 값을 가지는 칸의 구간의 나머지는 0이다.
무슨 말이냐면 1이 있는 1번과 4번의 값은 입력 배열에서 1과 1+2+3+1한 값이다 즉 4번에서 1번을 뺀 2 3 1 이 구간의 합을 3으로 나누게되면 0으로 나누어 떨어진다.
같은 나머지 값을 가지고 있다는 것은 두 구간의 사이가 결국 3으로 나누어 떨어지는 수의 차이만큼 벌어져있다는 소리이다.</p>
<p>글로 설명하는데 한계가 있어서 뭔가 확연하게 이해하기 쉬울 수는 없을 것이라 생각되서 이 <a href="https://youtu.be/Ud-qe0t5KA8">영상</a>을 추천한다.
나도 이 문제를 이해하는데 도움을 많이 받은 영상이다.</p>
<p>이제 그럼 결과인 7은 어떻게 나오는 것이냐면
나머지 배열의 0의 갯수 3 + 2개의 1에서 한 구간을 뽑는 경우의 수(2C2) + 3개의 0에서 한 구간을 뽑는 경우의 수 (3C2)로 결과값인 7이 도출된다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[백준] 11660 합 구하기 5 - Java]]></title>
            <link>https://velog.io/@yuki-kim/%EB%B0%B1%EC%A4%80-11660-%ED%95%A9-%EA%B5%AC%ED%95%98%EA%B8%B0-5-Java</link>
            <guid>https://velog.io/@yuki-kim/%EB%B0%B1%EC%A4%80-11660-%ED%95%A9-%EA%B5%AC%ED%95%98%EA%B8%B0-5-Java</guid>
            <pubDate>Sun, 15 Jan 2023 10:54:08 GMT</pubDate>
            <description><![CDATA[<h3 id="문제">문제</h3>
<p><img src="https://velog.velcdn.com/images/yuki-kim/post/19c3cb65-2816-404d-a05f-d0de5ecd8035/image.png" alt="">
<a href="https://www.acmicpc.net/problem/11660">링크</a></p>
<hr>
<h3 id="코드">코드</h3>
<pre><code class="language-java">import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.*;

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

        int[][] inputArray = new int[N + 1][N + 1];
        for (int i = 1; i &lt; inputArray.length; i++) {
            st = new StringTokenizer(br.readLine());
            for (int j = 1; j &lt; inputArray[i].length; j++) {
                inputArray[i][j] = Integer.parseInt(st.nextToken());
            }
        }

        int[][] sumArray = new int[N + 1][N + 1];
        for (int i = 1; i &lt; sumArray.length; i++) {
            for (int j = 1; j &lt; sumArray[i].length; j++) {
                sumArray[i][j] = sumArray[i][j - 1] + sumArray[i - 1][j] - sumArray[i - 1][j - 1] + inputArray[i][j];
            }
        }

        StringBuilder sb = new StringBuilder();
        for (int i = 0; i &lt; M; i++) {
            st = new StringTokenizer(br.readLine());
            int x1 = Integer.parseInt(st.nextToken());
            int y1 = Integer.parseInt(st.nextToken());
            int x2 = Integer.parseInt(st.nextToken());
            int y2 = Integer.parseInt(st.nextToken());

            sb.append(sumArray[x2][y2] - sumArray[x1 - 1][y2] - sumArray[x2][y1 - 1] + sumArray[x1 -1][y1 - 1])
                    .append(&quot;\n&quot;);
        }
        br.close();
        System.out.print(sb);
    }
}</code></pre>
<hr>
<h3 id="리뷰">리뷰</h3>
<p><img src="https://velog.velcdn.com/images/yuki-kim/post/56c4cf1c-4dde-447c-9996-d042053a119d/image.png" alt=""></p>
<p>이전에 풀었던 구간합 문제는 1차원배열이고 이번 문제는 2차원배열에서의 구간합 문제이다.</p>
<p>복잡해보이지만 원리는 동일하다.
처음 봤을 때는 이해가 안갔는데 그림으로 이해하는 편이 쉽게 이해할 수 있는 것 같다.</p>
<h4 id="구간합-배열-작성하기">구간합 배열 작성하기</h4>
<p>2차원배열의 구간합 배열을 구하기 위해서는
<img src="https://velog.velcdn.com/images/yuki-kim/post/0ab7f1d4-ed50-4779-9228-3ab1b8924f4e/image.png" alt=""></p>
<p>1차원배열에서 이전 인덱스의 구간의 합에 본인 자리에 입력받은 배열의 값을 더해주었듯이 같은 맥락으로 생각하면 된다.</p>
<p>같은 행에서 이전 인덱스의 구간합 값 + 같은 열에서 이전 인덱스의 구간합 값을 더하고
겹치는 부분을 빼주고 본인 자리의 입력받은 배열값을 더해주면 되는 것이다.
<code>sumArray[i][j] = sumArray[i][j - 1] + sumArray[i - 1][j] - sumArray[i - 1][j - 1] + inputArray[i][j];</code></p>
<h4 id="구간합-배열을-이용한-구간-사이의-합-구하기">구간합 배열을 이용한 구간 사이의 합 구하기</h4>
<p>이전에 1차원배열에서의 i부터 j구간까지의 합을 구할 때 구간합 배열에서
처음부터 j까지의 구간합 즉 <code>배열[j]</code> 의 값에서 필요없는 처음부터 i - 1구간을 뺐던 것처럼 생각하면 간단하다.</p>
<p>이차원 배열에서는
<img src="https://velog.velcdn.com/images/yuki-kim/post/fb7abdff-3bf7-45e0-a8cc-28e46b4f16b9/image.png" alt=""></p>
<p>이 구간의 합을 얻고싶으면
<img src="https://velog.velcdn.com/images/yuki-kim/post/c27b6d2f-d372-479f-99e0-002158ae0e14/image.png" alt="">
<img src="https://velog.velcdn.com/images/yuki-kim/post/39941ab9-e932-400a-912c-dd09efdb4521/image.png" alt=""></p>
<p>주황색 구간합(3, D) 값에서 빨간색 부분인 구간합(3,A)와 구간합(1,D)를 빼주고 빨간색 부분에서 유일하게 겹치는 구간합(1,A) 부분을 더해주면된다.</p>
<p>이 공식이 코드의 
<code>sumArray[x2][y2] - sumArray[x1 - 1][y2] - sumArray[x2][y1 - 1] + sumArray[x1 -1][y1 - 1]</code> 
이 부분인 것이다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[백준] 11659 구간 합 구하기 4 - Java]]></title>
            <link>https://velog.io/@yuki-kim/%EB%B0%B1%EC%A4%80-11659-%EA%B5%AC%EA%B0%84-%ED%95%A9-%EA%B5%AC%ED%95%98%EA%B8%B0-4-Java</link>
            <guid>https://velog.io/@yuki-kim/%EB%B0%B1%EC%A4%80-11659-%EA%B5%AC%EA%B0%84-%ED%95%A9-%EA%B5%AC%ED%95%98%EA%B8%B0-4-Java</guid>
            <pubDate>Sun, 15 Jan 2023 10:37:07 GMT</pubDate>
            <description><![CDATA[<h3 id="문제">문제</h3>
<p><img src="https://velog.velcdn.com/images/yuki-kim/post/f22cb739-f64e-4fde-81b9-471a5d17d1f0/image.png" alt="">
<a href="https://www.acmicpc.net/problem/11659">링크</a></p>
<hr>
<h3 id="코드">코드</h3>
<pre><code class="language-java">import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.*;

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

        int[] sumArray = new int[N + 1];
        st = new StringTokenizer(br.readLine());
        for (int i = 1; i &lt; sumArray.length; i++) {
            sumArray[i] = sumArray[i -1] + Integer.parseInt(st.nextToken());
        }

        StringBuilder sb = new StringBuilder();
        for (int k = 0; k &lt; M; k++) {
            st = new StringTokenizer(br.readLine());
            int i = Integer.parseInt(st.nextToken());
            int j = Integer.parseInt(st.nextToken());
            sb.append(sumArray[j] - sumArray[i - 1]).append(&quot;\n&quot;);
        }
        br.close();
        System.out.print(sb);
    }
}</code></pre>
<hr>
<h3 id="리뷰">리뷰</h3>
<p><img src="https://velog.velcdn.com/images/yuki-kim/post/557c6873-d063-46ff-88bd-15441ea8246c/image.png" alt=""></p>
<p>문제를 어느정도 풀고나니 대부분 계산 등을 이용한 구현문제가 대부분이였고 요즘 알고리즘도 하나씩 공부해야 될 것 같아 누적합(구간합) 알고리즘에 대해 공부하며 문제를 풀어보았다.</p>
<p>문제를 얼핏보면 입력받은 수를 배열에 넣어놓고 i부터 j까지 그냥 배열에서 바로 더해서 출력하면 되는게 아닌가 싶지만 알고리즘 문제의 경우 평소에 우리가 빠르게 풀던 반복문을 그냥 돌리는 형태로는 시간 복잡도에 의해 실패가 되는 경우가 많다.</p>
<p>최악의 경우 배열이 100,000의 크기를 가지고 100,000개의 질의가 들어오면 <code>100,000 * 100,000 = 100억</code>
100억건의 연산으로 보통 1억당 1초로보니 100초가 걸려 문제의 조건인 1초를 훨씬 뛰어넘는 시간이다.</p>
<p>그런데 입력받은 배열의 구간별로 합을 저장한 배열을 만들게되면 질의 1건당 O(1)의 연산이 필요해 100,000건으로 여유롭게 시간 제한안에 들어가게된다.
(시간 복잡도 개념이 아직 익숙하지 않아 위의 계산들이 틀릴 수 있다.)</p>
<p>결론은 시간초과를 막으려면 구간합 알고리즘을 사용해야한다는 결론이다.</p>
<p>구간합의 값은 구간합 배열의 이전 인덱스의 값 + 입력받은 배열의 현재 인덱스 값이다. (<code>sumArray[i] = sumArray[i - 1] + array[i]</code>)
반복문을 통해 입력받는 동시에 바로 구간합 배열을 만들어주고 입력을 통해 들어온 구간범위에 따른 값을 출력해주면된다.</p>
<p>구간합은 i부터 j의 범위공식은 <code>summArray[j] - sumArray[i - 1]</code>이다.</p>
<p>[0][0][X][X][X] 3부터 5의 구간 범위를 구하고 싶으면
[X][X][X][X][X] 1부터 5의 구간합에서
[X][X][O][O][O] 1부터 2의 구간합을 빼주면 구할 수 있는 것이다.
즉 <code>sumArray[5] - sumArray[2]</code>로 위의 공식과 동일하다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[백준] 25305 커트라인 - Java]]></title>
            <link>https://velog.io/@yuki-kim/%EB%B0%B1%EC%A4%80-25305-%EC%BB%A4%ED%8A%B8%EB%9D%BC%EC%9D%B8-Java</link>
            <guid>https://velog.io/@yuki-kim/%EB%B0%B1%EC%A4%80-25305-%EC%BB%A4%ED%8A%B8%EB%9D%BC%EC%9D%B8-Java</guid>
            <pubDate>Sat, 14 Jan 2023 08:03:54 GMT</pubDate>
            <description><![CDATA[<h3 id="문제">문제</h3>
<p><img src="https://velog.velcdn.com/images/yuki-kim/post/386f9e57-2dc3-4c66-8245-4d32d60d9c15/image.png" alt="">
<a href="https://www.acmicpc.net/problem/25305">링크</a></p>
<hr>
<h3 id="코드">코드</h3>
<pre><code class="language-java">import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.*;

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

        int[] scores = new int[N];
        st = new StringTokenizer(br.readLine());
        for (int i = 0; i &lt; scores.length; i++) {
            scores[i] = Integer.parseInt(st.nextToken());
        }
        Arrays.sort(scores);

        System.out.println(scores[scores.length - k]);
    }
}</code></pre>
<hr>
<h3 id="리뷰">리뷰</h3>
<p><img src="https://velog.velcdn.com/images/yuki-kim/post/eddaa385-bc3f-4cb0-99ee-19c5332ea6f4/image.png" alt=""></p>
<p>N명의 학생 중 k명이 상을 받고 상을 받은 사람 중 제일 낮은 성적을 구하는 문제이다.</p>
<p>즉, 정렬을 한 상태의 배열에서 상을 받는 사람들 중 첫번째 인덱스를 출력하면 된다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[백준] 11047 동전 0 - Java]]></title>
            <link>https://velog.io/@yuki-kim/%EB%B0%B1%EC%A4%80-11047-%EB%8F%99%EC%A0%84-0-Java</link>
            <guid>https://velog.io/@yuki-kim/%EB%B0%B1%EC%A4%80-11047-%EB%8F%99%EC%A0%84-0-Java</guid>
            <pubDate>Sat, 14 Jan 2023 08:01:14 GMT</pubDate>
            <description><![CDATA[<h3 id="문제">문제</h3>
<p><img src="https://velog.velcdn.com/images/yuki-kim/post/50c29b33-2a6a-4bf6-86cf-6dccbc3afd66/image.png" alt="">
<a href="https://www.acmicpc.net/problem/11047">링크</a></p>
<hr>
<h3 id="코드">코드</h3>
<pre><code class="language-java">import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.*;

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

        Integer[] coins = new Integer[N];
        for (int i = 0; i &lt; coins.length; i++) {
            coins[i] = Integer.parseInt(br.readLine());
        }
        Arrays.sort(coins, Collections.reverseOrder());

        int count = 0;
        for (Integer coin : coins) {
            if (K &gt;= coin) {
                count += K / coin;
                K %= coin;
            }
        }
        System.out.println(count);
    }
}</code></pre>
<hr>
<h3 id="리뷰">리뷰</h3>
<p><img src="https://velog.velcdn.com/images/yuki-kim/post/a160bfc4-e855-4ff0-9427-fd6ba9a84a64/image.png" alt=""></p>
<p>동전 갯수의 최솟값을 구하기위해서는 동전의 리스트를 내림차순으로 정렬하여 큰 돈 부터 교환하게끔하여 구현한다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[백준] 9094 수학적 호기심 - Java]]></title>
            <link>https://velog.io/@yuki-kim/%EB%B0%B1%EC%A4%80-9094-%EC%88%98%ED%95%99%EC%A0%81-%ED%98%B8%EA%B8%B0%EC%8B%AC-Java</link>
            <guid>https://velog.io/@yuki-kim/%EB%B0%B1%EC%A4%80-9094-%EC%88%98%ED%95%99%EC%A0%81-%ED%98%B8%EA%B8%B0%EC%8B%AC-Java</guid>
            <pubDate>Fri, 13 Jan 2023 11:38:40 GMT</pubDate>
            <description><![CDATA[<h3 id="문제">문제</h3>
<p><img src="https://velog.velcdn.com/images/yuki-kim/post/06217aff-3be2-4fc5-9f22-d34c910f9015/image.png" alt="">
<a href="https://www.acmicpc.net/problem/9094">링크</a></p>
<hr>
<h3 id="코드">코드</h3>
<pre><code class="language-java">import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
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());
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i &lt; T; i++) {
            StringTokenizer st = new StringTokenizer(br.readLine());
            int n = Integer.parseInt(st.nextToken());
            int m = Integer.parseInt(st.nextToken());
            int count = 0;

            for (int j = 1; j &lt; n; j++) {
                for (int k = j + 1; k &lt; n; k++) {
                    if (((j * j) + (k * k) + m) % (j * k) == 0) count++;
                }
            }
            sb.append(count).append(&quot;\n&quot;);
        }
        br.close();
        System.out.print(sb);
    }
}</code></pre>
<hr>
<h3 id="리뷰">리뷰</h3>
<p><img src="https://velog.velcdn.com/images/yuki-kim/post/27d73786-534d-4ab5-accd-337f201dcad9/image.png" alt=""></p>
<p><code>(a^2 + b^2 + m) / (a * b)</code> 가 정수가 된다는건 해당 식의 결과가 나머지가 없이 딱 나누어 떨어져야 된다는 것이다.</p>
<p>즉, <code>(a^2 + b^2 + m) % (a * b)</code> 가 0이여야 한다는 것이다.
구현은 브루트포스 문제답게 반복문을 이용하면 된다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[백준] 2587 대표값2 - Java]]></title>
            <link>https://velog.io/@yuki-kim/%EB%B0%B1%EC%A4%80-2587-%EB%8C%80%ED%91%9C%EA%B0%922-Java</link>
            <guid>https://velog.io/@yuki-kim/%EB%B0%B1%EC%A4%80-2587-%EB%8C%80%ED%91%9C%EA%B0%922-Java</guid>
            <pubDate>Fri, 13 Jan 2023 05:03:26 GMT</pubDate>
            <description><![CDATA[<h3 id="문제">문제</h3>
<p><img src="https://velog.velcdn.com/images/yuki-kim/post/f5f1b3f5-27f3-417e-95e4-a099227240c7/image.png" alt="">
<a href="https://www.acmicpc.net/problem/2587">링크</a></p>
<hr>
<h3 id="코드">코드</h3>
<pre><code class="language-java">import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Arrays;

public class Main {
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        int[] scores = new int[5];

        for (int i = 0; i &lt; scores.length; i++) {
            scores[i] = Integer.parseInt(br.readLine());
        }
        Arrays.sort(scores);

        StringBuilder sb = new StringBuilder();
        sb.append((int) (Arrays.stream(scores).average().getAsDouble())).append(&quot;\n&quot;);
        sb.append(scores[2]);
        System.out.print(sb);
    }
}</code></pre>
<hr>
<h3 id="리뷰">리뷰</h3>
<p><img src="https://velog.velcdn.com/images/yuki-kim/post/9bb179d9-3347-47aa-87ac-c7fbda573224/image.png" alt=""></p>
<p>성적을 5개 입력받고 평균점수와 중앙값을 출력하는 문제이다.
5개를 입력받으면서 바로 배열을 이용해 담아주고 정렬을 하면 매우 간단하게 중앙값을 구할 수 있다.</p>
<p>평균은 반복문으로 구해도되고 위의 풀이처럼 스트림을 이용해 평균을 구하는 방법이 있다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[프로그래머스 코딩테스트 입문 완료 회고]]></title>
            <link>https://velog.io/@yuki-kim/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-%EC%BD%94%EB%94%A9%ED%85%8C%EC%8A%A4%ED%8A%B8-%EC%9E%85%EB%AC%B8-%EC%99%84%EB%A3%8C-%ED%9A%8C%EA%B3%A0</link>
            <guid>https://velog.io/@yuki-kim/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-%EC%BD%94%EB%94%A9%ED%85%8C%EC%8A%A4%ED%8A%B8-%EC%9E%85%EB%AC%B8-%EC%99%84%EB%A3%8C-%ED%9A%8C%EA%B3%A0</guid>
            <pubDate>Fri, 13 Jan 2023 04:39:41 GMT</pubDate>
            <description><![CDATA[<p><img src="https://velog.velcdn.com/images/yuki-kim/post/256c1122-5b53-43de-8e42-3d97d0345075/image.png" alt=""></p>
<h3 id="시작하게-된-계기">시작하게 된 계기</h3>
<p>회고라고 하기엔 정말 짧고 글을 안쓰기에는 뭔가 그래도 노력했는데 아쉬워서 남기는 글이다.</p>
<p>국비지원 과정을 수강하고있으면서 자바를 거쳐 스프링, 스프링 부트를 배워가는 중에 자바를 활용하는 점이 뭔가 아쉽게 느껴졌다.</p>
<p>어려운 기술을 쓰고싶다기보다는 뭔가 기본기를 사용하는데 생각하는데 걸리는 시간도 많고 다양한 해결 방법이 떠오르지 않았었다.</p>
<p>그래서 다른 공부를 하면서 코딩테스트 준비를 조금씩 하는게 어떨까 싶었다.
(실제로 도움이 되는지는 잘 모르겠지만 😅 무작정 시작해본것 같다)</p>
<p>그렇다고해서 일전에 아예 문제를 안풀어본것은 아니고 자바를 배울 때 과제 형식으로 몇몇 문제를 풀었었는데 그 때는 당장 배운 것을 바로 활용하려니 잘 사용하지 못해서 오히려 약간의 자괴감이 드는 듯한 기분이여서 유쾌한 경험은 아니였던 것 같다.</p>
<br>

<h3 id="어떻게-문제를-해결했나">어떻게 문제를 해결했나?</h3>
<p>인터넷에 흔히 코딩테스트 문제라고 올라오는 DFS, BFS, ~탐색, 등 바로 푸는 것은 힘들 것이라 판단해서 자신감도 키울겸(?) 백준에서는 단계별로 문제풀이, 프로그래머스에서는 레벨 0의 문제를 풀어보기 시작했다.</p>
<p>일단 제목이 프로그래머스니까 프로그래머스 위주로 작성해보면 처음에는 간단한 출력문제들이 많아서 편하게 풀었는데 가끔씩 레벨 0문제가 맞는건가 싶은 문제도 있었다.</p>
<p>그래도 객관적으로 보면 많은 문제는 아니지면 내 기준에서 많은 문제를 풀어보고 어느정도 맞는 방식의 공부법을 얻을 수 있었던 것 같다.</p>
<p>문제랑 조건들을 보고 바로 떠오르는 경우에는 바로 풀고
바로 떠오르지 않는 경우에는 조금 생각하는 시간을 가져본다.</p>
<p>만약 떠오르는데 코드 작성이 힘들면은 그 떠오르는 메소드나 방식을 검색을 통해 사용법을 보고 코드를 작성해보는 식으로 진행했다.
그리고 도저히 못 풀 것 같은 문제는 다른 사람들의 풀이를 최대한 다양하게 보는 방식으로 진행했다. 언어가 다르더라도 일단 확인해보았다.</p>
<p>언어가 다르더라도 결국 비슷한 맥락으로 돌아가고 메서드나 일부 사용법이 살짝 다를 뿐이지 문제를 해결하는 매커니즘 자체는 비슷한 것 같았다.</p>
<p>문제를 해결하고나서도 위와 같은 맥락으로 다른 사람들의 풀이를 살펴보는 것이 중요하다고 생각한다.
그렇게해서 스트림이나 람다같은 생소한 것들도 사용해보면서 어느정도 익힐 수 있는 좋은 기회였다고 생각한다.</p>
<br>

<h3 id="후기">후기</h3>
<p>후기라고 해야하나 아직까진 구현 위주의 문제만 풀어봤기에 자료구조나 알고리즘 등은 잘 모르지만 조금씩 지금처럼 꾸준히 도전해 볼 생각이다.</p>
<p>코딩테스트가 일종의 토익이라는 말처럼 실제 실무에서는 쓰기 애매한 경우도 있다고는 하지만 코드 작성의 경험을 늘리는데는 확실한 동기부여와 약간의 성취감을 주는 좋은 재료라고 생각한다.
(이제 레벨 100문제 풀고 백준도 막 실버에 도착한 수준에 이런 말은 무모할 수 있지만 😁)</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[프로그래머스] 다음에 올 숫자 - Java]]></title>
            <link>https://velog.io/@yuki-kim/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-%EB%8B%A4%EC%9D%8C%EC%97%90-%EC%98%AC-%EC%88%AB%EC%9E%90-Java</link>
            <guid>https://velog.io/@yuki-kim/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-%EB%8B%A4%EC%9D%8C%EC%97%90-%EC%98%AC-%EC%88%AB%EC%9E%90-Java</guid>
            <pubDate>Thu, 12 Jan 2023 12:55:16 GMT</pubDate>
            <description><![CDATA[<h3 id="문제">문제</h3>
<p><img src="https://velog.velcdn.com/images/yuki-kim/post/ef53eb4f-14fc-4780-8b59-65df24998333/image.png" alt="">
<a href="https://school.programmers.co.kr/learn/courses/30/lessons/120924">링크</a></p>
<hr>
<h3 id="코드">코드</h3>
<pre><code class="language-java">class Solution {
    public int solution(int[] common) {
        if (common[1] - common[0] == common[2] - common[1]) {
            return common[common.length - 1] + (common[1] - common[0]);
        }
        else return common[common.length -1] * (common[1] / common[0]);
    }
}</code></pre>
<hr>
<h3 id="리뷰">리뷰</h3>
<p><img src="https://velog.velcdn.com/images/yuki-kim/post/994a8108-21ab-4600-980a-d181a2d79850/image.png" alt=""></p>
<p>등차수열인지 등비수열인지 판단해서 다음에 올 숫자를 출력하도록 한다.</p>
<p>등차수열은 앞의 항에 일정한 수를 더하여 얻어지는 수열
등비수열은 앞의 항에 일정한 수를 곱하여 얻어지는 수열
이렇게 구분할 수 있다.</p>
<p>그럼 이 둘을 어떻게 구분할까?
간단한건 등차수열인지 알아보면 된다.
일정한 수를 더하여 얻어지는 수열이라고 정의되어있듯이</p>
<p>첫 번째 인덱스와 두 번째 인덱스의 차이와 세 번째 인덱스와 두 번째 인덱스의 차이가 같다면 등차수열이다.
그러므로 자연스럽게 같지않으면 등비수열이되기 때문에</p>
<p>마지막 인덱스에 등차수열이면 차이값을 더해주고 등비수열이면 곱해주면 문제를 해결할 수 있다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[프로그래머스] 연속된 수의 합 - Java]]></title>
            <link>https://velog.io/@yuki-kim/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-%EC%97%B0%EC%86%8D%EB%90%9C-%EC%88%98%EC%9D%98-%ED%95%A9-Java</link>
            <guid>https://velog.io/@yuki-kim/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-%EC%97%B0%EC%86%8D%EB%90%9C-%EC%88%98%EC%9D%98-%ED%95%A9-Java</guid>
            <pubDate>Thu, 12 Jan 2023 12:29:39 GMT</pubDate>
            <description><![CDATA[<h3 id="문제">문제</h3>
<p><img src="https://velog.velcdn.com/images/yuki-kim/post/9b86cd69-cf98-4c0a-9117-bbed0e5950f4/image.png" alt="">
<a href="https://school.programmers.co.kr/learn/courses/30/lessons/120923">링크</a></p>
<hr>
<h3 id="코드">코드</h3>
<pre><code class="language-java">class Solution {
    public int[] solution(int num, int total) {
        int[] answer = new int[num];
        int middleValue = total / num;
        int startNumber = middleValue - ((total % num == 0) ? num / 2 : (num / 2) - 1);

        for (int i = 0; i &lt; num; i++) {
            answer[i] = startNumber + i;
        }

        return answer;
    }
}</code></pre>
<hr>
<h3 id="리뷰">리뷰</h3>
<p><img src="https://velog.velcdn.com/images/yuki-kim/post/5e24a8bd-f7c1-4576-a6a2-49016a50218b/image.png" alt=""></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[프로그래머스] 종이 자르기 - Java]]></title>
            <link>https://velog.io/@yuki-kim/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-%EC%A2%85%EC%9D%B4-%EC%9E%90%EB%A5%B4%EA%B8%B0-Java</link>
            <guid>https://velog.io/@yuki-kim/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-%EC%A2%85%EC%9D%B4-%EC%9E%90%EB%A5%B4%EA%B8%B0-Java</guid>
            <pubDate>Thu, 12 Jan 2023 11:34:06 GMT</pubDate>
            <description><![CDATA[<h3 id="문제">문제</h3>
<p><img src="https://velog.velcdn.com/images/yuki-kim/post/2007e039-9944-4e92-86d8-6dac776c02e1/image.png" alt="">
<a href="https://school.programmers.co.kr/learn/courses/30/lessons/120922">링크</a></p>
<hr>
<h3 id="코드">코드</h3>
<pre><code class="language-java">class Solution {
    public int solution(int M, int N) {
        return (M * N) - 1;
    }
}</code></pre>
<hr>
<h3 id="리뷰">리뷰</h3>
<p><img src="https://velog.velcdn.com/images/yuki-kim/post/a97b211b-a7ee-46ee-9eff-df8020efd69d/image.png" alt=""></p>
<p>공통되는 규칙이 있지만 뭔가 설명하기는 애매한 문제같다 😁
어떤 종이든 겹치지않게 1 X 1 형식으로 자른다.
가로 세로를 나누어서 생각해보자 만약 도화지가 2 X 5라면 우선 길이가 긴 세로인 5를 1칸씩 자른다고 생각하면 4번의 가위질을 하면 5개의 1이 나온다.</p>
<p>거기에 가로가 2이므로 5개를 한번씩 가위질하면 총 9번이 된다.</p>
<p>결국 종합하면 M X N 의 도화지의 경우 <code>(M * N) - 1</code>의 가위질을 하게된다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[프로그래머스] 문자열 밀기 - Java]]></title>
            <link>https://velog.io/@yuki-kim/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-%EB%AC%B8%EC%9E%90%EC%97%B4-%EB%B0%80%EA%B8%B0-Java</link>
            <guid>https://velog.io/@yuki-kim/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-%EB%AC%B8%EC%9E%90%EC%97%B4-%EB%B0%80%EA%B8%B0-Java</guid>
            <pubDate>Thu, 12 Jan 2023 11:22:34 GMT</pubDate>
            <description><![CDATA[<h3 id="문제">문제</h3>
<p><img src="https://velog.velcdn.com/images/yuki-kim/post/26c489ee-c6c1-424e-8ffc-bbf38edb79c9/image.png" alt="">
<a href="https://school.programmers.co.kr/learn/courses/30/lessons/120921">링크</a></p>
<hr>
<h3 id="코드">코드</h3>
<p>풀이 1.</p>
<pre><code class="language-java">class Solution {
    public int solution(String A, String B) {
        int count = 0;

        String word = A;
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i &lt; A.length(); i++) {
            if (word.equals(B)) return count;
            sb.append(word.substring(word.length() - 1))
                    .append(word, 0, word.length() -1);
            word = sb.toString();
            sb.setLength(0);
            count++;
        }
        return -1;
    }
}</code></pre>
<p>풀이 2.</p>
<pre><code class="language-java">class Solution {
    public int solution(String A, String B) {
        return (B + B).indexOf(A);
    }
}</code></pre>
<hr>
<h3 id="리뷰">리뷰</h3>
<p>첫번째 풀이방식은 반복문을 돌며 <code>substring()</code>을 통해 단어의 맨뒤를 잘라 새로운 단어의 맨 앞에 붙이고 나머지 단어를 뒤에 이어붙혀 한 칸씩 이동하는 새로운 단어를 만들어주며 B와 같은 값이 나오는지 확인한다.</p>
<p>두번째 풀이방식은 풀고나서 보게된 풀이방법인데 이렇게 간단한 방법이 있을 줄은 생각못했다 😳</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[백준] 2750 수 정렬하기 - Java]]></title>
            <link>https://velog.io/@yuki-kim/%EB%B0%B1%EC%A4%80-2750-%EC%88%98-%EC%A0%95%EB%A0%AC%ED%95%98%EA%B8%B0-Java</link>
            <guid>https://velog.io/@yuki-kim/%EB%B0%B1%EC%A4%80-2750-%EC%88%98-%EC%A0%95%EB%A0%AC%ED%95%98%EA%B8%B0-Java</guid>
            <pubDate>Thu, 12 Jan 2023 11:13:05 GMT</pubDate>
            <description><![CDATA[<h3 id="문제">문제</h3>
<p><img src="https://velog.velcdn.com/images/yuki-kim/post/9a97c78e-82c4-4656-bdeb-6966d852528a/image.png" alt="">
<a href="https://www.acmicpc.net/problem/2750">링크</a></p>
<hr>
<h3 id="코드">코드</h3>
<pre><code class="language-java">import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Arrays;

public class Main {
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        int N = Integer.parseInt(br.readLine());
        int[] arr = new int[N];

        for (int i = 0; i &lt; N; i++) {
            arr[i] = Integer.parseInt(br.readLine());
        }
        br.close();

        Arrays.sort(arr);
        StringBuilder sb = new StringBuilder();
        for (int value : arr) {
            sb.append(value).append(&quot;\n&quot;);
        }
        System.out.print(sb);
    }
}</code></pre>
<hr>
<h3 id="리뷰">리뷰</h3>
<p><img src="https://velog.velcdn.com/images/yuki-kim/post/6b03b3a2-798a-4b2c-a72d-adb3503459d5/image.png" alt=""></p>
<p>입력받은 숫자를 오름차순으로 정렬하는 문제로 배열에 담아 정렬하면 간단하게 구현할 수 있다.</p>
]]></description>
        </item>
    </channel>
</rss>